Contrôler une LED par le web (IDE 1.0)

Cela ne marche pas, msg est vide lorsque j'envoie client.print("2:"+Tempa"); soit par ex 2:18.5
mais lorsque j'envoie sans les : ca marche (j'ai 218.5 )

J'ai réessayé par ta méthode soit

 String json = "{\"start\":";
    json+=2;                                      
    json+=",\"Tempa\":";
    json+=Tempa;
    json+="}";

La ca marche j'ai {"start":2,"Tempa":18.5}
or je ne voudrais que 2:18.5 puis par traitement de la chaine récupérer 2 et 18.5 pour les affecter à des variables a et b par ex..

Ca y est j'ai trouvé...

de l'arduino j'envoie : "{"var1":x,"var2":y}" x=2 y = 5
dans la fonction log(msg) je rajoute
var objet = JSON.parse(msg);
var Data1 =objet.var1; // Data = 2
var Data2 =objet.var2; // Data = 5

Bonjour,

J’ai pas mal avancé à partir des éléments qu’a fournis Osaka. Encore mille fois merci à lui.

Je les ai petit à petit transformés pour que cela puisse correspondre à mon projet, et faire quelque chose de fonctionnel.
Ce que j’ai fait correspond à un bricolage, que beaucoup d’entre vous vont juger infâme, mais ça me permets d’apprendre, et de faire avancer mon projet.

Je sais que tôt ou tard il va falloir que je passe en PHP avec une petite base de données MySql, mais pour le moment ce n’est pas à ma portée (je verrai probablement cela durant les longues soirées d’hiver).

Pour l’instant je « gère » deux sorties en fonction de plages horaires (3 pour chaque sortie), avec une possibilité de « marche forcée ».
Je vais avoir à gérer une quinzaine de sorties (pour commencer), je compte faire 3 pages avec 5 sorties par page, je pense que plus de 5 sortie par page, ce sera illisible (déjà là, il faudra s’accrocher !) Mais pour les aspects visuels, je verrai encore après, avant tout je veux que cela fonctionne, je joins une copie d’écran avec les 2 sorties.

J’ai deux questions qui vont très probablement vous paraître triviales :

  1. Comment faire savoir à l’arduino quelle est la page (des 3) qui est concernée ? Ce qui reviendrait à transmettre un identifiant de la page active. J’ai essayé en vain, mais mes compétences en html sont très limitées.

  2. Comment écrire à un endroit précis dans le tableau ? Dans la dernière colonne, à coté de « Electrovanne », j’aimerai écrire « activée » ou « désactivée » en fonction de l’état de l’électrovanne. Actuellement je n’arrive à l’écrire qu’en dessous du tableau « EV1 activée ou désactivée » et « EV2 activée ou désactivée ».

Je ne sais pas si je suis bien clair dans mes questions.

Je joins l'ensemble des fichiers.

Bien à vous

Domoweb.zip (40.1 KB)

Domo_RTC_LCD_PCF8574lib_UIA_PH_DS18B20_LED_SD_NTP.ino (35.7 KB)

Brisebee:
Je les ai petit à petit transformés pour que cela puisse correspondre à mon projet, et faire quelque chose de fonctionnel.
Ce que j’ai fait correspond à un bricolage, que beaucoup d’entre vous vont juger infâme, mais ça me permets d’apprendre, et de faire avancer mon projet.

C'est comme ça qu'on apprend et qu'on retiens. :wink:

Brisebee:
Je sais que tôt ou tard il va falloir que je passe en PHP avec une petite base de données MySql, mais pour le moment ce n’est pas à ma portée (je verrai probablement cela durant les longues soirées d’hiver).

Pour les petites quantités de données et ce que tu désires faire tu verras les bdd c'est très simple.

Brisebee:

  1. Comment faire savoir à l’arduino quelle est la page (des 3) qui est concernée ? Ce qui reviendrait à transmettre un identifiant de la page active. J’ai essayé en vain, mais mes compétences en html sont très limitées.

Ici tu peux faire une fonction par formulaire ou si identique ajouter un ou des paramètres pour les différencier et ainsi séparer la fonction send() qui pourra alors envoyer différentes données, même autre que formulaires.

function sendForm(form)  //fonction qui sera appelé depuis la page html, form = numero du formulaire
{
  //appel de la fonction send(msg) chargé d'envoyé les différente valeurs trouvee grace a la fonction $(id)
  send(
	{
	  fnum: form,
	  hda1: $('hda1').value, mda1: $('mda1').value, hfa1: $('hfa1').value, mfa1: $('mfa1').value,
	  hda2: $('hda2').value, mda2: $('mda2').value, hfa2: $('hfa2').value, mfa2: $('mfa2').value,
	  hda3: $('hda3').value, mda3: $('mda3').value, hfa3: $('hfa3').value, mfa3: $('mfa3').value,
	  hdb1: $('hdb1').value, mdb1: $('mdb1').value, hfb1: $('hfb1').value, mfb1: $('mfb1').value,
	  hdb2: $('hdb2').value, mdb2: $('mdb2').value, hfb2: $('hfb2').value, mfb2: $('mfb2').value,
	  hdb3: $('hdb3').value, mdb3: $('mdb3').value, hfb3: $('hfb3').value, mfb3: $('mfb3').value,
	  EV1: $('EV1').checked, EV2: $('EV2').checked
	}
  );
}

function send(msg)
{
  // requête post vers socket.php avec les différentes valeurs du formulaire (msg) 
  jQuery.post("socket.php", msg, 
	function(data) //data contiendra la ou les données en retour de la requête
	{
	  $("retour").innerHTML = data; // on integre dans la balise portant l'id "retour" les data de retour
	});
}

function $(id)
{
  return document.getElementById(id); // fonction '

Dans la page html, appel de la fonction adapté à ton formulaire spécifique ou différent (différencier ici par un paramètre (1) que tu changeras sur chaque pages ou chaque formulaires de page).

<div><button id="bouton" onclick="sendForm(1)">Valider</button></div>

Entre (), c'est ici que php te serait utile comme les pages et formulaires sont assé similaire et répétitives, mais bon une chose à la fois :D.

Brisebee:
2) Comment écrire à un endroit précis dans le tableau ? Dans la dernière colonne, à coté de « Electrovanne », j’aimerai écrire « activée » ou « désactivée » en fonction de l’état de l’électrovanne. Actuellement je n’arrive à l’écrire qu’en dessous du tableau « EV1 activée ou désactivée » et « EV2 activée ou désactivée ».

Ça c'est le truc le plus ch... avec le html, savoir placer ses données ou autres au bon endroit c'est tout une sinécure, c'est pour celà que je n'ai jamais chercher de ce côté là niveau emplois :sleeping:.
En séparent la case en deux colonne ça ne marche pas ? recherche l'element html par son 'id'
}


Dans la page html, appel de la fonction adapté à ton formulaire spécifique ou différent (différencier ici par un paramètre (1) que tu changeras sur chaque pages ou chaque formulaires de page).

§DISCOURSE_HOISTED_CODE_1§


Entre (), c'est ici que php te serait utile comme les pages et formulaires sont assé similaire et répétitives, mais bon une chose à la fois :D.

> Brisebee:
> 2) Comment écrire à un endroit précis dans le tableau ? Dans la dernière colonne, à coté de « Electrovanne », j’aimerai écrire « activée » ou « désactivée » en fonction de l’état de l’électrovanne. Actuellement je n’arrive à l’écrire qu’en dessous du tableau « EV1 activée ou désactivée » et « EV2 activée ou désactivée ».

Ça c'est le truc le plus ch... avec le html, savoir placer ses données ou autres au bon endroit c'est tout une sinécure, c'est pour celà que je n'ai jamais chercher de ce côté là niveau emplois :sleeping:.
En séparent la case en deux colonne ça ne marche pas ?

Merci Osaka,
Je vais essayer ce que tu proposes pour identifier la page.

Pour ce qui concerne la position de "activée" ou "désactivé" dans une colonne, je n'ai pas essayé, comme tu le laisses entendre.
De toute manière, je ne sais pas comment indiquer où placer un bout de texte.

@+

Brisebee:
Pour ce qui concerne la position de "activée" ou "désactivé" dans une colonne, je n'ai pas essayé, comme tu le laisses entendre.
De toute manière, je ne sais pas comment indiquer où placer un bout de texte.

Pour placer des éléments à un endroit spécifique :
http://www.siteduzero.com/tutoriel-3-13566-le-positionnement-en-css.html#ss_part_4
http://www.siteduzero.com/tutoriel-3-13522-l-alignement.html

Merci Osaka,

J'avais vu sur le site du zéro, j'ai même acheté le bouquin. Mais pour ce que j'en ai compris c'est un alignement ou un placement par rapport à un endroit précis, et non pas tout simplement à la suite d'un mot, un peu comme dans un texte à trou où un mot viendrait s'insérer à la suite d'un autre, ou dans une cellule d'un tableau, je pensais que c'était une (ou des) fonction(s) existante(s) qui m'avai(en)t échappé.

De toute façon ce n'est pas important, c'est plus cosmétique que fonctionnel.
@+

En fait le texte en lui même tu ne sais pas le positionner, par contre les balise type bloc ou inline oui, donc pour inséré un texte différent, décalé ou autre tu auras 3 balise span par exemple, une contenant le texte à gauche, un au centre (celui qui sera décalé) et un à sa droite.
Enfin c'est clair qu'il faut joué et bricoler pour obtenir ce que l'on désire la plus part du temps :(.

Bonjour,
J’ai bien avancé.
J’ai réussi à faire fonctionner mon système avec deux pages web, une première page pour les 5 électrovannes « aspergeurs » et une seconde page pour les 5 électrovannes « goutte à goutte ». Cela fonctionne très bien, je peux leur affecter des plages horaires et lire et afficher (pas encore exactement où je veux, mais j’ai laissé tomber pour le moment car c’est un détail) les états des entrées correspondantes.
Mon problème du moment est le suivant :
Lorsque j’utilise la fonctionnalité de mise à jour automatique de l’heure par un serveur NTP, celle-ci fonctionne, mais je n’arrive plus à me connecter au serveur web apache, il doit y avoir un conflit, mais c’est au delà de mes compétences.
J’ai refait des essais avec uniquement ces deux fonctionnalités avec les « programmes de base » :

  1. l’échange de données avec le serveur web (actuellement en local : serveur apache) programmes fournis par Osaka => fonctionne très bien
#include <SPI.h>
#include <Ethernet.h>

byte mac[] = {  0x90, 0xA2, 0xDA, 0x00, 0x6D, 0x86 }; // a remplacer
byte ip[] = { 192,168,0,49 }; // a remplacer

EthernetServer server(8888); // 1080 a remplacer si différent fonctionne également avec 8888 => à modifier alors dans php
byte nb = 0;

void setup() 
{

  Serial.begin(9600);

  Ethernet.begin(mac, ip);
  server.begin();

}


void loop() 
{
  EthernetClient client = server.available();
  
  if (client) 
  {
    nb++;
    if (client.connected()) 
    {
      while (client.available()) 
      {
        char c = client.read();
        Serial.write(c); //on affiche dans le monitor les caractère reçu

        if(!client.available())
        {

          client.write("j'ai bien reçu la requete "); //réponse avec write
          client.print(nb, DEC); // réponse avec print (nb = nombre de requêtes)
          delay(1);
          
          client.stop();
        }
      }
      Serial.println (); // retour à la ligne dans serial monitor après chaque réception des données
    }
  }
}
  1. la lecture de données sur un serveur NTP => fonctionne très bien
#include <SPI.h>         
#include <Ethernet.h>
#include <EthernetUdp.h>

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {  
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

unsigned int localPort = 8888;      // local port to listen for UDP packets

IPAddress timeServer(192, 43, 244, 18); // time.nist.gov NTP server

const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message

byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets 

// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

void setup() 
{
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  // start Ethernet and UDP
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    for(;;)
      ;
  }
  Udp.begin(localPort);
}

void loop()
{
  sendNTPpacket(timeServer); // send an NTP packet to a time server

    // wait to see if a reply is available
  delay(1000);  
  if ( Udp.parsePacket() ) {  
    // We've received a packet, read the data from it
    Udp.read(packetBuffer,NTP_PACKET_SIZE);  // read the packet into the buffer

    //the timestamp starts at byte 40 of the received packet and is four bytes,
    // or two words, long. First, esxtract the two words:

    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);  
    // combine the four bytes (two words) into a long integer
    // this is NTP time (seconds since Jan 1 1900):
    unsigned long secsSince1900 = highWord << 16 | lowWord;  
    Serial.print("Seconds since Jan 1 1900 = " );
    Serial.println(secsSince1900);               

    // now convert NTP time into everyday time:
    Serial.print("Unix time = ");
    // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
    const unsigned long seventyYears = 2208988800UL;     
    // subtract seventy years:
    unsigned long epoch = secsSince1900 - seventyYears;  
    // print Unix time:
    Serial.println(epoch);                               


    // print the hour, minute and second:
    Serial.print("The UTC time is ");       // UTC is the time at Greenwich Meridian (GMT)
    Serial.print((epoch  % 86400L) / 3600); // print the hour (86400 equals secs per day)
    Serial.print(':');  
    if ( ((epoch % 3600) / 60) < 10 ) {
      // In the first 10 minutes of each hour, we'll want a leading '0'
      Serial.print('0');
    }
    Serial.print((epoch  % 3600) / 60); // print the minute (3600 equals secs per minute)
    Serial.print(':'); 
    if ( (epoch % 60) < 10 ) {
      // In the first 10 seconds of each minute, we'll want a leading '0'
      Serial.print('0');
    }
    Serial.println(epoch %60); // print the second
  }
  // wait ten seconds before asking for the time again
  delay(10000); 
}

// send an NTP request to the time server at the given address 
unsigned long sendNTPpacket(IPAddress& address)
{
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE); 
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12]  = 49; 
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;

  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp: 		   
  Udp.beginPacket(address, 123); //NTP requests are to port 123
  Udp.write(packetBuffer,NTP_PACKET_SIZE);
  Udp.endPacket(); 
}
  1. la lecture de données NTP dans setup, et échange de données avec le serveur web => seul la lecture NTP fonctionne
    le programme en fichier joint

Voici ce que renvoi le serveur apache au bout d’un moment :
Warning: socket_connect() [function.socket-connect]: unable to connect [0]: Une tentative de connexion a ?ou?ar le parti connect??a pas r?ndu convenablement au-del??une certaine dur?ou une connexion ?blie a ?ou?ar l?h?de connexion n?a pas r?ndu. in C:\Program Files (x86)\EasyPHP-5.3.9\www\Osaka1\socket.php on line 11

Warning: socket_write() [function.socket-write]: unable to write to socket [0]: Une requ? d?envoi ou de r?ption de donn? n?a pas ? autoris?car le socket n?est pas connect?t (lors de l?envoi sur un socket datagramme en utilisant un appel sendto) aucune adresse n?a ? fournie. in C:\Program Files (x86)\EasyPHP-5.3.9\www\Osaka1\socket.php on line 12

Auriez-vous une idée ?
Bien à vous

UdpNtpClient_web.ino (5.2 KB)

Yop Bribri,
Il y a déjà conflit avec le même port utilisé (8888) pour deux connexions simultané différente.

EthernetServer server(8888);

unsigned int localPort = 8888;      // local port to listen for UDP packets
Udp.begin(localPort);

Merci pour ta réponse Osaka,

Je me suis dit ça un moment, j'avais remis 1080 dans la partie de programme que tu m'as fourni ( ainsi que dans php), mais cela n’a rien donné, alors j’ai remis en 8888.
@+

Je viens de faire un rapide teste avec quelque modif et ça marche.
Je me suis d'abord charger du ntp et mis tout ce qui le concerne en local à une fonction comme utile qu'à l'initialisation.

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

byte mac[] = {  0x90, 0xA2, 0xDA, 0x00, 0x6D, 0x86 };  // mac adresse propre à l'arduino
byte ip[] = { 192,168,1,109 }; // ip locale propre à l'arduino

EthernetServer server(1080); // 1080 a remplacer si différent fonctionne également avec ???? => à modifier alors dans php

byte nb = 0;

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

  Ethernet.begin(mac, ip);
  print_NTP_Time(NTP()); // on s'occupe d'abord de récupérer l'heure via serveur NTP+affichage
  server.begin(); // ensuite du serveur de socket
}

void loop()
{
  EthernetClient client = server.available();
  
  if (client) 
  {
    nb++;
    if (client.connected()) 
    {
      while (client.available()) 
      {
        char c = client.read();
        Serial.write(c); //on affiche dans le monitor les caractère reçu

        if(!client.available())
        {
          client.write("j'ai bien reçu la requete "); //réponse avec write
          client.print(nb, DEC); // réponse avec print (nb = nombre de requêtes)
          delay(1);
          
          client.stop();
        }
      }
      Serial.println (); // retour à la ligne dans serial monitor après chaque réception des données
    }
  }
}

unsigned long NTP() // retourne le nombre de sec. depuis 1 Jan 1970. (Unix time)
{ 
  EthernetUDP Udp;
  IPAddress timeServer(192, 43, 244, 18); // time.nist.gov NTP server
    
  const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message
  byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets 
  memset(packetBuffer, 0, NTP_PACKET_SIZE); //initialise toute les "case" du tableau à 0
  
  //construction de la requete
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12]  = 49; 
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;

  Udp.begin(8888);		   
  Udp.beginPacket(timeServer, 123); //NTP requests are to port 123
  Udp.write(packetBuffer,NTP_PACKET_SIZE);
  Udp.endPacket(); 

  delay(1000);  
  if ( Udp.parsePacket() ) 
  {  
    Udp.read(packetBuffer,NTP_PACKET_SIZE);
    Udp.stop();

    const unsigned long seventyYears = 2208988800UL; 
    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
    unsigned long secsSince1900 = highWord << 16 | lowWord;
    
    return secsSince1900 - seventyYears;
  }
  
  return 0;
}

void print_NTP_Time(unsigned long epoch) // fonction utilitaire, affiche l'heure UTC
{
  Serial.print("Unix time = "); // Unix time starts on Jan 1 1970. In seconds, that's 2208988800: 
  Serial.println(epoch); // print Unix time:                           

  // print the hour, minute and second:
  Serial.print("The UTC time is ");       // UTC is the time at Greenwich Meridian (GMT)
  Serial.print((epoch  % 86400L) / 3600); // print the hour (86400 equals secs per day)
  Serial.print(':');  
  if ( ((epoch % 3600) / 60) < 10 ) // In the first 10 minutes of each hour, we'll want a leading '0'
  {
    Serial.print('0');
  }
  Serial.print((epoch  % 3600) / 60); // print the minute (3600 equals secs per minute)
  Serial.print(':'); 
  if ( (epoch % 60) < 10 ) // In the first 10 seconds of each minute, we'll want a leading '0'
  {
    Serial.print('0');
  }
  Serial.println(epoch %60); // print the second
}

Merci beaucoup Osaka,

Je vais pouvoir tester cela ce soir.

@+

Je viens de tester, cela ne fonctionne pas chez moi.

  • tel quel, NTP fonctionne, mais pas l'échange de données

  • si je commente (/* */) la partie suivante :

  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    for(;;)
      ;
  }

j'obtiens :
Unix time = 0
The UTC time is 0:00:00
pseudo=a&frites=false&pays=france

Il semble y avoir un problème avec Ethernet.begin
Mais comme je n’y comprends pas grand-chose !
@+

Brisebee:

  • si je commente (/* */) la partie suivante :
  if (Ethernet.begin(mac) == 0) {

Serial.println("Failed to configure Ethernet using DHCP");
   for(;:wink:
     ;
 }




j'obtiens :
Unix time = 0
The UTC time is 0:00:00
pseudo=a&frites=false&pays=france

Mauvais copier coller de ma part, tu peux supprimer cette partie.
En faisant divers testes j'ai pu constater ce comportement, la gestion des différent socket tcp ou udp semble parfois chaotique.
Je réédite mon poste précédent pour être certain d'avoir mis le bon (fonctionnel chez moi).

Juste aux cas ou je suis sous core 1.0.1 .

J'ai toujours :
Unix time = 0
The UTC time is 0:00:00

Le reste fonctionne

osaka:
Juste aux cas ou je suis sous core 1.0.1 .

Moi pareil

J'utilise un serveur local EasyPHP 5.3.9 est ce que cela peut venir de ça ?

Brisebee:
J'utilise un serveur local EasyPHP 5.3.9 est ce que cela peut venir de ça ?

Je pense pas comme tout est fonctionnel de ce côté là, essaie une fois en ajoutant un petit delay :

  Ethernet.begin(mac, ip);
  delay(100);
  print_NTP_Time(NTP());

Ca y est, ça marche !!!

A force d'essayer des trucs, j'ai trouvé qu'en faisant :

  Ethernet.begin(mac);
  print_NTP_Time(NTP()); // on s'occupe d'abord de récupérer l'heure via serveur NTP+affichage
  
  Ethernet.begin(mac, ip);
  server.begin();

Cela fonctionne.

Je suis bien évidemment incapable de comprendre pourquoi !

Encore merci Osaka pour ton aide.
@+

Brisebee:
Je suis bien évidemment incapable de comprendre pourquoi !

Je suis également incapable de dire pourquoi. :grin:
C'est un peux comme faire un reset du shield wizenet en remettant à jour les données de configuration réseau (ip, mac), pourtant fonctionnel sans chez moi et surtout que le code ajouter n'est qu'à la suite du code posant problème.
Je soupçonne le besoin d'un petit delay que le code ajouter ajoute :sweat_smile:.

Enfin ça fonctionne :grin: .

osaka:
[Je soupçonne le besoin d'un petit delay que le code ajouter ajoute :sweat_smile:.

J'avais essayé de mettre des delay à peu près à toutes les étapes, sans effet.
@+