Requêtes HTTP (GET / POST) impossibles ? (Ethernet)

Bonjour à tous !

J'ai un projet : une alarme maison à base d'arduino Uno, Ethernet (ENC28J60), Sirène 12v via simple relais, récepteur 433 pour le déclenchement via des détecteurs 433Mhz

J'ai tout placé dans un boitier et préparé l'intégralité du code chargé de détecter une intrusion et envoyer une alerte (via une requête HTTP à pushingbox.com, intermédiaire que je suis obligé d'utiliser pour m'envoyer un SMS via Free Mobile et autres), tout fonctionne bien avec Ethercard, le SMS est reçu environ 5 sec après le déclenchement d'un capteur, c'est très efficace...

Le problème est que je dois utiliser Blynk pour armer/désarmer l'alarme et connaitre son état en temps réel. J'ai fait un deuxième code totalement fonctionnel qui permet d'interagir avec l'alarme, seulement ce dernier utilise UIPEthernet...

Les 2 librairies ne pouvant pas cohabiter dans le même code, il me faut faire une requête HTTP GET ou POST via UIPEthernet. J'ai pas mal cherché sur internet, ainsi que dans les exemples de UIPEth, impossible de recevoir la notification (j'ai essayé une bonne dizaine de combinaisons comme if (client.connect("api.pushingbox.com",80) { client.print("POST /pushingbox?devid=v000000000000"); client.stop() } (par exemple en mettant devid=[...] sur une autre ligne client.print, POST au lieu de GET, etc...)

Voici la documentation de Pushingbox : https://www.pushingbox.com/help.php

Merci par avance de m'éclairer un peu, je ne sais plus quoi essayer à force...

Bonsoir,

D’après ce que j’ai vu, la bibliothèque “UIPEthernet” remplace avec profit la bibliothèque “Ethercard” pour les communications Ethernet avec le ENC28J60.

Dans votre code fonctionnel (Ethercard) qui envoie la requête vers le serveur pushingbox, il doit y avoir quelque part l’envoi de cette requête. Il vous faut :

  • repérer cette partie du code,
  • en “extraire” la requête pour voir ce que vous envoyez exactement au serveur,
  • dans votre nouveau programme, sous UIPEthernet, coder et envoyer la même requête.

Pour trouver la requête, cherchez GET ou POST (en majuscules).

Bonne bidouille,

MicroQuettas

Salut MicroQuettas,

J'ai vérifié dans le code qui marche avec Ethercard, la ligne de code qui envoie la requête est la suivante :

ether.browseUrl(PSTR("/pushingbox?devid="), Id_PIR_Abri_Bois, website, my_callback);

avec :

char Id_PIR_Abri_Bois[] = "[Mon ID Pushingbox]"; const char website[] PROGMEM = "api.pushingbox.com";

ainsi que :

// called when the client request is complete static void my_callback (byte status, word off, word len) { Serial.println(">>>"); Ethernet::buffer[off+300] = 0; Serial.print((const char*) Ethernet::buffer + off); Serial.println("..."); }

J'ai tenté de reproduire (en vain) cette fonction, rien ne passe avec client.print etc...

La fonction ether.browseUrl renvoie à ça dans Ethercard.h

    static void browseUrl (const char *urlbuf, const char *urlbuf_varpart,
                           const char *hoststr, const char *additionalheaderline,
                           void (*callback)(uint8_t,uint16_t,uint16_t));

    /**   @brief  Prepare HTTP request
    *     @param  urlbuf Pointer to c-string URL folder
    *     @param  urlbuf_varpart Pointer to c-string URL file
    *     @param  hoststr Pointer to c-string hostname
    *     @param  callback Pointer to callback function to handle response
    *     @note   Request sent in main packetloop
    */
    static void browseUrl (const char *urlbuf, const char *urlbuf_varpart,
                           const char *hoststr,
                           void (*callback)(uint8_t,uint16_t,uint16_t));

    /**   @brief  Prepare HTTP post message
    *     @param  urlbuf Pointer to c-string URL folder
    *     @param  hoststr Pointer to c-string hostname
    *     @param  additionalheaderline Pointer to c-string with additional HTTP header info
    *     @param  postval Pointer to c-string HTML Post value
    *     @param  callback Pointer to callback function to handle response
    *     @note   Request sent in main packetloop
    */

Mais je ne suis pas plus avancé à propos de l’équivalent de cette fonction avec UIPEthernet…

Bonjour,

Il faut regarder dans le Ethercard.cpp pour voir exactement ce que fait la fonction browseUrl et lui écrire un équivalent qui utilise la bibliothèque UIPEthernet.

Envoyer une requête POST c'est relativement facile, mais si j'ai bien compris votre projet, il faut se connecter séquentiellement sur pushingbox et puis sur Blynk. Donc il faut gérer les deux connexions. Avec un peu de chance, browseUrl en gère une de bout en bout, mais il faut regarder.

Je vais vous regarder cela, mais pas aujourd'hui car j'ai la famille.

Encore une question : ce que vous envoyez à pushingbox est constant ? Si c'est le cas, où si le nombre de caractères envoyé ne bouge pas, cela va grandement simplifier la requête POST.

Bonne bidouille

MicroQuettas

Bonjour !

En fait, pour que tout fonctionne il faudrait être connecté en permanence à Blynk (la fonction Blynk.run() permet cela lorsqu’elle est exécutée en boucle dans void loop) et n’établir une connexion à Pushingbox uniquement en cas d’intrusion (soit en théorie très rarement, soit dans le cas d’une effraction, soit si le signal de désactivation d’une télécommande 433 n’est pas reçu par l’arduino ou tout bêtement un oubli…)

J’ai également remarqué que lorsque
if (client.connect(“api.pushingbox.com”,80) {
client.print(“POST /pushingbox?devid=v000000000000”);
client.stop()
}
est exécuté, dans le moniteur série s’affiche " Getting IP from DHCP " puis "Bynk connected Ready "etc (exactement comme lors du démarrage), et évidemment aucune notification de la part de Pushingbox n’est reçue…

Par ailleurs, merci beaucoup pour le temps que vous consacrez à m’aider…

PS: Je joint quelques photos du projet ainsi que le code complet, si ça peut servir à quelqu’un…


(Le schéma a pas mal évolué au fil de l’avancement du projet, au départ l’arduino ne devait pas gérer l’activation de l’alarme mais carrément être allumé et éteint par un relais 433, la LED a été remplacée par un afficheur 4*7segment visible en photo, le garage n’a plus son propre relais 433 mais un commandé par arduino au même titre que les sirènes et l’extracteur d’air

  • Dans le code, j’ai inclus le DS3231 dont la pile, commandée en Chine, ne m’arrivera que dans 1 mois, car je souhaiterais que l’alarme surveille automatiquement toute la cave pendant la nuit, je vais rajouter ça dans le code prochainement…
#include <EtherCard.h>

#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();

#include <Wire.h>
#include <DS3231.h>
DS3231 clock;
RTCDateTime dt;

#define VCC_PIN 5 // source 5V up to 40mA
#define GND_PIN 2 // ground up to 40mA
#define DATA_PIN 3 // data 433 In
#define SIREN_PIN A1 // Relay of 12V sirens
#define GARAGE_PIN A2 // Relay of Garage trigger
#define THIRD_RELAY_PIN A3 // Relay of... nothing yet

#define Remote_Cmd 5529424
#define Door_Cuisine 1392005
#define Win_Bureau 1197077
#define Door_Chaufferie 1397855
#define Win_Abri_Bois 1797842
#define PIR_Garage A0
#define PIR_Abri_Bois A1

char IdDoorCuisine[] = "v*/*/*/*/*/*//*//*/";
char IdWinBureau[] = "v*/*/*/*/*/*//*//*/";
char IdDoorChaufferie[] = "v*/*/*/*/*/*//*//*/";
char IdWinAbriBois[] = "v*/*/*/*/*/*//*//*/";
char IdPIRGarage[] = "v*/*/*/*/*/*//*//*/";

static byte mymac[] = {0x24,0x99,0x42,0xAD,0x30,0x32};   // Be sure this address is unique in your network

const char website[] PROGMEM = "api.pushingbox.com";
byte Ethernet::buffer[700];
Stash stash;
boolean DEBUG = true;


void setup()
{
  Serial.begin(9600);
 
pinMode(SIREN_PIN, OUTPUT);
pinMode(GARAGE_PIN, OUTPUT);
pinMode(THIRD_RELAY_PIN, OUTPUT);
digitalWrite(SIREN_PIN, HIGH);
digitalWrite(GARAGE_PIN, HIGH);
digitalWrite(THIRD_RELAY_PIN, HIGH);

pinMode(DATA_PIN, INPUT);
pinMode(GND_PIN, OUTPUT);
pinMode(VCC_PIN, OUTPUT);
digitalWrite(GND_PIN, LOW);
digitalWrite(VCC_PIN, HIGH);

if(DEBUG){Serial.println("\n[getDHCPandDNS]");}
 
  //
  //***Depending of your Shield, you may have to try this line instead of the second***//
  //if(ether.begin(sizeof Ethernet::buffer, mymac) == 0)
  if(ether.begin(sizeof Ethernet::buffer, mymac, 10) == 0)
    if(DEBUG){Serial.println( "Failed to access Ethernet controller");}
 
  // Wait until we have an IP from the DHCP
  while(!ether.dhcpSetup()){
    if(DEBUG){Serial.println("Error: DHCP failed. Can't get an IP address, let's retry...");}
  }
 
  if(DEBUG){
    ether.printIp("My IP: ", ether.myip);
    ether.printIp("Netmask: ", ether.netmask);
    ether.printIp("GW IP: ", ether.gwip);
    ether.printIp("DNS IP: ", ether.dnsip);
  }

  if (!ether.dnsLookup(website))
    if(DEBUG){Serial.println("DNS failed");}
  if(DEBUG){ether.printIp("Server: ", ether.hisip);}

mySwitch.enableReceive(1);  // Receiver on interrupt 1 => that is pin D3


}


void loop()
{

ether.packetLoop(ether.packetReceive());
 
if (mySwitch.available())
{
  int value = mySwitch.getReceivedValue();

  if ( mySwitch.getReceivedValue() == Door_Cuisine ) {
    ether.browseUrl(PSTR("/pushingbox?devid="), IdDoorCuisine, website, my_callback);
    digitalWrite(SIREN_PIN, LOW); }
  if ( mySwitch.getReceivedValue() == Win_Bureau ) {
    ether.browseUrl(PSTR("/pushingbox?devid="), IdWinBureau, website, my_callback);
    digitalWrite(SIREN_PIN, LOW); }
  if ( mySwitch.getReceivedValue() == Door_Chaufferie ) {
    ether.browseUrl(PSTR("/pushingbox?devid="), IdDoorChaufferie, website, my_callback);
    digitalWrite(SIREN_PIN, LOW); }

  mySwitch.resetAvailable();
  delay(500);
}

  if ( analogRead(A0) > 500 ) {
    Serial.println("A0 Garage detected. Starting eth transmission");
    ether.browseUrl(PSTR("/pushingbox?devid="), IdPIRGarage, website, my_callback);
    Serial.println("A0 Garage detected. Ending eth transmission");
    digitalWrite(SIREN_PIN, LOW);
    delay(10000); }

  if ( analogRead(A1) > 500 ) {
    Serial.println("A1 Abri Bois detected. Starting eth transmission");
    ether.browseUrl(PSTR("/pushingbox?devid="), IdPIRGarage, website, my_callback);
    Serial.println("A1 Abri Bois detected. Ending eth transmission");
    digitalWrite(SIREN_PIN, LOW);
    delay(10000); }

}

// called when the client request is complete
static void my_callback (byte status, word off, word len)
{
  Serial.println(">>>");
  Ethernet::buffer[off+300] = 0;
  Serial.print((const char*) Ethernet::buffer + off);
  Serial.println("...");
}

Code fonctionnel avec Blynk uniquement :

#define BLYNK_PRINT Serial


#include <UIPEthernet.h>
#include <BlynkSimpleUIPEthernet.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "*/*/*/*/*/*/*/*/*/*/*/*/*/*/";

EthernetClient client;

int state = 0;

void setup()
{
  // Debug console
  Serial.begin(9600);

  Blynk.begin(auth);

  // You can also specify server:
  //Blynk.begin(auth, "blynk-cloud.com", 8442);
  //Blynk.begin(auth, IPAddress(192,168,1,100), 8442);
}

void loop()
{
  Blynk.run();
}

BLYNK_WRITE(V1) // Canal de modification de l'état
{
  int V1Data = param.asInt();
  Blynk.virtualWrite(V0,"CONTROL");
  delay(1000);
  if (V1Data == 0) state = 0;
  if (V1Data == 1) state = 1;
  if (V1Data == 2) state = 2;
}

BLYNK_WRITE(V2) // Canal d'actualisation de l'état
{
  int V2Data = param.asInt();
  Blynk.virtualWrite(V0,"REFRESH");
  delay(500);
  if (state == 0) {
    Blynk.virtualWrite(V0,"Off (Veille)");
    Blynk.virtualWrite(V1,0);
    Blynk.virtualWrite(V4,"Ready");
    Blynk.virtualWrite(V11,0);
    Blynk.virtualWrite(V12,0);
  }
  if (state == 1) {
    Blynk.virtualWrite(V0,"Mode Complet");
    Blynk.virtualWrite(V1,1);
    Blynk.virtualWrite(V4,"OK");
    Blynk.virtualWrite(V11,255);
    Blynk.virtualWrite(V12,0);
  }
  if (state == 2) {
    Blynk.virtualWrite(V0,"Mode Partiel");
    Blynk.virtualWrite(V1,2);
    Blynk.virtualWrite(V4,"OK");
    Blynk.virtualWrite(V11,0);
    Blynk.virtualWrite(V12,255);
  }
  if (state == 3) {
    Blynk.virtualWrite(V0,"Mode Nuit");
    Blynk.virtualWrite(V1,0);
    Blynk.virtualWrite(V4,"OK");
    Blynk.virtualWrite(V11,0);
    Blynk.virtualWrite(V12,0);
  }

}

BLYNK_WRITE(V3) // Canal de programmation de nuit
{
  int V3Data = param.asInt();
  if (V3Data == 0) state = 0;
  if (V3Data == 1) state = 3;
}

Bonjour Finette,

J'ai un regardé de plus près les bibliothèques et je pense avoir trouvé une approche en 3 étapes :

  • modifier le code de votre premier programme pour le faire tourner sur UIEthernet. Il utilise une requête GET (et non une POST) ce qui est une bonne nouvelle, car plus simple. Dans un premier temps, on va faire un code simple (pas très robuste), pour voir si ça marche,
  • ensuite, on va intégrer les deux. L'idée c'est d'avoir 2 clients : 1 pour le Blynk, un autre pour la pushingbox, le deuxième se connectant suivant nécessité. Encore ici, on va utiliser le code non optimisé de l'étape 1, pour voir si ça marche,
  • enfin, si tout va bien, il faudra optimiser et surtout rendre plus robuste.

Je posterai les morceaux de code, écrits d'après vos deux posts. Comme je ne peux pas les compiler dans votre environnement, il vous faudra corriger les petits bugs et surtout adapter à votre système (comptes etc.).

Votre projet m'intéresse car je n'ai pas utilisé ces techniques et que j'ai une carte avec un AVR 328 et un ENC28J60 qui dort dans un tiroir car je la pensais incompatible avec les Arduino, ce qui n'est plus le cas avec ces bibliothèques.

Voilà, la suite au prochain numéro,

MicroQuettas

Bonjour,

Voila la première partie :

#include <string.h>
#include <stdio.h>
#include <Streaming.h>       /* Super pratique !! */
#include <avr/pgmspace.h>

#include <UIPEthernet.h>

#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();

#include <Wire.h>
#include <DS3231.h>
DS3231 clock;
RTCDateTime dt;

#define VCC_PIN 5 // source 5V up to 40mA
#define GND_PIN 2 // ground up to 40mA
#define DATA_PIN 3 // data 433 In
#define SIREN_PIN A1 // Relay of 12V sirens
#define GARAGE_PIN A2 // Relay of Garage trigger
#define THIRD_RELAY_PIN A3 // Relay of... nothing yet

#define Remote_Cmd 5529424
#define Door_Cuisine 1392005
#define Win_Bureau 1197077
#define Door_Chaufferie 1397855
#define Win_Abri_Bois 1797842
#define PIR_Garage A0
#define PIR_Abri_Bois A1

#define CA_Cuisine 0x0001        /* Code alarme */
#define CA_WBureau 0x0002
#define CA_Chaufferie 0x0004
#define CA_Garage 0x0100
#define CA_AbrisBois 0x0200

/* Pour économiser la RAM, on met toutes ces chaînes en mémoire
 * programme
 * ???????? A vous de mettre les bonnes valeurs ????????? */
 
P(PIdDoorCuisine) = "v*/*/*/*/*/*//*//*/";
P(PIdWinBureau) = "v*/*/*/*/*/*//*//*/";
P(PIdDoorChaufferie) = "v*/*/*/*/*/*//*//*/";
P(PIdWinAbriBois) = "v*/*/*/*/*/*//*//*/";
P(PIdPIRGarage) = "v*/*/*/*/*/*//*//*/";

static byte mymac[] = {0x24,0x99,0x42,0xAD,0x30,0x32};  
// Be sure this address is unique in your network

#define DEBUG true  /* Switch de compilation, à commenter
                      * dans la version définitive */

/* Le client pour la pushingbox */
EthernetClient clientPB;

/* La requête à envoyer :
 *
 * GET /pushingbox?devid=<Id> HTTP/1.1
 * Host: api.pushingbox.com
 * Connection: close
 * <ligne vide>
 *
 * La ligne 1 est la plus longue.
 * Pour économiser la mémoire, on va la ligne 1 puis les autres
 * ensemble.
 * On va dimensionner la ligne à 72, à voir en fonction de la
 * longueur de vos identifiants  ??? à vérifier ???
 *
 * On range tous les éléments de ligne en mémoire programme
 * pour économiser la RAM.
 */

P(PLi_1a) = "GET /pushingbox?devid=";
P(PLi_1b) = " HTTP/1.1\r\n";
P(PL2a) =  "Host: ";
P(PWebSite) = "api.pushingbox.com";
P(PL2b) =  "\r\nConnection: close\r\n\r\n";

#define CLgLine 72

/*************************** Routines *********************************/
void SentPBRqt(uint16_t MAlarm)
  {
  char Line[CLgLine];
  
  /* Préparation ligne 1 */
  strcpy_P(Line, PLi_1a);
  
  /* Selon valeur du masque d'alarme, ajout de l'identifiant */
  switch (MAlarm)
    {
    case CA_Cuisine:
      strcat_P(Line, PIdDoorCuisine);
      break;

    case CA_WBureau:
      strcat_P(Line, PIdWinBureau);
      break;

    case CA_Chaufferie:
      strcat_P(Line, PIdDoorChaufferie);
      break;
      
    case CA_Garage:
      strcat_P(Line, PIdPIRGarage);
      break;

    case CA_AbrisBois:
      strcat_P(Line, PIdWinAbriBois);
      break;
    
    default:
      break;  /* Sécurité, on ne fait rien */
    }

  strcat_P(Line, PL1b);  /* Fin de la ligne 1 */

  #ifdef DEBUG
  Serial << F("Ligne 1 = ") << Line << endl;  /* Vérification */
  #endif
  
  clientPB.write(Line, strlen(Line));
  
  /* Lignes suivantes */
  strcpy_P(Line, PL2a);
  strcat_P(Line, PWebSite);
  strcat_P(Line, PL2b);
  
  #ifdef DEBUG
  Serial << F("Ligne 2 = ") << Line << endl;  /* Vérification */
  #endif
  
  clientPB.write(Line, strlen(Line));

  }

void GetPBReply()
  {  /* Réponse du serveur sur le port série pour débug */
  char c;
  
  #ifdefDEBUG
  Serial << endl;
  #endif
          
  if (clientPB.available())
    {
    c = clientPB.read();
    #ifdef DEBUG
    Serial << c ;
    #endif
    }

  #ifdefDEBUG
  Serial << endl;
  #endif
  }


/****************************** Setup *********************************/
void setup()
{
  Serial.begin(9600);
 
  pinMode(SIREN_PIN, OUTPUT);
  pinMode(GARAGE_PIN, OUTPUT);
  pinMode(THIRD_RELAY_PIN, OUTPUT);
  digitalWrite(SIREN_PIN, HIGH);
  digitalWrite(GARAGE_PIN, HIGH);
  digitalWrite(THIRD_RELAY_PIN, HIGH);

  pinMode(DATA_PIN, INPUT);
  pinMode(GND_PIN, OUTPUT);
  pinMode(VCC_PIN, OUTPUT);
  digitalWrite(GND_PIN, LOW);
  digitalWrite(VCC_PIN, HIGH);
  

  /* Etablissement connexion Ethernet */ 
  while (Ethernet.begin(mymac) == 0)
    {  /* Echec de connexion Ethernet */
    #ifdef DEBUG
    Serial << F("Echec connexion Ethernet") << endl;
    #endif
    delay(5000);  /* Attend 5s et ré-essaie jusqu'à ce que la 
                   * connexion s'établisse */
    }
  

  mySwitch.enableReceive(1);  // Receiver on interrupt 1 => that is pin D3


  }

/***************************** Loop ***********************************/
void loop()
  {
  uint16_t Alarm = 0;
  uint16_t m = 1;     /* Masque pour explorer les alarmes */
  uint16_t r,         /* Résultat de l'exploration */
  uint8_t i;
  boolean Transmit = false;
  char Site[20];  /* Tampon pour le site - ajuster si nécessaire */
 
  if (mySwitch.available())
    {
    switch (mySwitch.getReceivedValue())
      {
      case Door_Cuisine:
        Alarm = CA_Cuisine;
        break;
      
      case Win_Bureau:
        Alarm = CA_WBureau;
        break;

      case Door_Chaufferie:
        Alarm = CA_Chaufferie;
        break;
    
      default:
        break;
      }
    
    mySwitch.resetAvailable();
    }

  if ( analogRead(A0) > 500 ) /* Je ne comprends pas bien pourquoi
                               * vous utilisez une entrée analogique */
    {
    Alarm |= CA_Garage;  /* On rajoute cette alarme si nécessaire */
    }

  if ( analogRead(A1) > 500 )
    {
    Alarm |= CA_AbrisBois;
    }
    
  if (Alarm)
    {  /* Il y a au moins une alarme */
    
    /* Connexion au serveur PB */
    strcpy_P(Site, WebSite);
    while (!Transmit)
      {
      if (clientPB.connect(Site, 80))
        {
        Transmit = true;
        #ifdef DEBUG
        Serial << F("Connecté à la PB") << endl;
        #endif
        }
        else
        {
        #ifdef DEBUG
        Serial << F("Erreur connexion PB") << endl;   
        #endif
        delay(5000);  /* On attend 5s avant de recommencer */
        }
      }
      
    }  /* Fin if alarme */
    
  if (Transmit)
    {   /* La connexion est établie, on peut transmettre */
    for (i = 0; i < 15 ; i++)  /* On explore le masque des alarmes
                                  * et on transmet à la PB */
      {
      r = Alarm & m;
      if (r)
        { /* Il y a une alarme sur ce canal */
        SentPBRqt(r) ;
        /* Réception de la réponse */

        GetPBReply();  /* Récupère la réponse de la PB */
                
        delay(1000);  /* ???? A ajuster ????*/
        }
        
      m = m << 1;   /* Canal d'alarme suivant */
      }
      
    /* Déconnexion */
    clientPB.stop();   
      
    }    /* Fin if transmit */
  }      /* Fin loop */

/***************************** Fin ************************************/

Comme vous êtes sur un Uno, j’ai un peu optimisé en utilisant la mémoire PROGMEM à chaque fois que possible. Il vous reste aussi à rajouter vos identifiants. S’ils sont longs, il faudra augmenter en conséquence la taille de la ligne avec la constante CLgLine.

J’utilise aussi la classe Streaming qui est super pratique pour le debug. Vous la trouverez sur le site Arduino (et en PJ). Vous dézippez et copiez le répertoire Streaming et ce qu’il contient dans le votre répertoire “libraries” (où vous avez déjà placé les autres bibliothèques).

Comme je n’ai pas compilé le code, il y a sans doute des erreurs. Si vous n’y arrivez pas, je vous aiderai.

Enfin, le code n’est pas prêt pour une utilisation opérationnelle : s’il n’arrive pas à établir la connexion, il réessaye jusqu’à ce qu’il y arrive, mais il ne fait rien d’autre en attendant. Comme je vous l’ai dit, il s’agit dans cette étape de voir si ça marche. On verra ensuite pour le rendre plus opérationnel.

Bonne bidouille et tenez moi au courant,

MicroQuettas.

Streaming.zip (2.29 KB)

Bonjour MicroQuettas,

Merci pour ce code bien commenté, je viens de le parcourir entièrement afin de comprendre son fonctionnement pour gérer les deux services, dès que je rentre chez moi j'essayerais de corriger le nécessaire si besoin et de l'uploader dans mon Duino, je vous tiendrais au courant du résultat...

Bonne journée ! Finette