Go Down

Topic: Contrôler une LED par le web (IDE 1.0) (Read 10934 times) previous topic - next topic

nadirovick

J'ajoute une petite synthèse, si j'ai bien compris bien sûre  XD





merci  :*
@+

osaka

Yop Yop,


() Je travail maintenant sur l'autre topic que je le trouve fort intéressant


Il y a un problème sur mon ancien projet comme la normalisation des websocket à beaucoup changer depuis, donc la partie serveur php n'est plus valable : le handshake n'est plus en md5 mais en sah1 et il y a un mask en plus sur les donnée maintenant (unmasking à effectuer en plus pour retrouvé ses données d'origines)  :~.
Donc c'est pour ses raisons que j'avais abandonné le projet comme la normalisation n'était et n'est toujours pas finalisé.
Bon maintenant il ne devrait plus y avoir trop de modif et elle devrait arrivé à terme donc je me suis refait un serveur de websocket mais en java cette fois ci (j'espère juste encore qu'on aura le choix du masking ou non une fois finalisé).


Les erreurs sont  pour le moment sur le sketch, je pense que c'est un problème de versionning
Sketch Arduino "je travail sur la version 1.0 de l'IDE":


J'avais du le faire avec une 0.22 ou ultérieure je crois.

nadirovick

Re tout le monde  :*,
Je n'arrive pas à  trouver la fonction  sendCmdJsonReturn()  :(, j'ai cherché sur la librairie

Code: [Select]
void action(uint8_t* data)
{
  String str = dduino.sendCmdJsonReturn(data);

  if(str != "0")
  {
    client.print(str);
  }
}


Peux-tu m'aider stp  =(
@+

osaka


Je n'arrive pas à  trouver la fonction  sendCmdJsonReturn()  :(, j'ai cherché sur la librairie


C'est la première fonction après le constructeur dans les fichiers de la lib  :smiley-mr-green: .

nadirovick

Euh  :smiley-eek:, désolé j'ai pas bien vu  :smiley-roll-sweat:
Ma question, elle sera la dernière J'espère  :smiley-mr-green:, j'arrive pas à comprendre le fonctionnement de la fonction runCMD, exactement cette portion, car j'essaye de bien comprendre ton code afin de pouvoir faire du débogage si je serai obligé.

Code: [Select]
case DIGITAL_WRITE:
{
if (data[4])
{
*digitalPinMap[data[3]].port |= 1 << digitalPinMap[data[3]].bit;
}
else
{
*digitalPinMap[data[3]].port &= ~(1 << digitalPinMap[data[3]].bit);
}

if(data[5])
{
data[4] = *digitalPinMap[data[3]].port & (1 << digitalPinMap[data[3]].bit);
return data;
}
}


*digitalPinMap[data[3]].port |= 1 << digitalPinMap[data[3]].bit; --------------------|
*digitalPinMap[data[3]].port &= ~(1 << digitalPinMap[data[3]].bit); ----------------|------->   Elles accomplissent quoi exactement
data[4] = *digitalPinMap[data[3]].port & (1 << digitalPinMap[data[3]].bit); --------|

Mes questions fréquentes montrent l'intérêt que je porte à ton travail que je trouve extrêmement intéressant  :*
Merci
@+

Brisebee

Bonjour,

Me voici de retour !
De temps à autre j'ai jeté un oeil sur le forum à distance, et j'ai vu que vous aviez bien avancé.
Je vais reprendre les posts un à un pour essayer de comprendre ce que vous avez fait (Osaka et Nadirovick), ce qui devrait pouvoir me permettre de progresser dans la compréhension de l'échange de données entre le serveur web et l'arduino.
Je vous poserai certainement des questions, soit en cas de blocage ou pour valider ma progression !

@+

osaka


*digitalPinMap[data[3]].port |= 1 << digitalPinMap[data[3]].bit; --------------------|
*digitalPinMap[data[3]].port &= ~(1 << digitalPinMap[data[3]].bit); ----------------|------->   Elles accomplissent quoi exactement
data[4] = *digitalPinMap[data[3]].port & (1 << digitalPinMap[data[3]].bit); --------|


Là d'après ce que je vois (parce que je ne me souviens plus de tout ce que j'avais fais  :smiley-mr-green: ), il s'agissait de manipuler les registres directement et non de passer pas la fonction digitalWrite() du core arduino.
La première ligne était pour mettre le bit du port correspondant à la pin arduino n°x à 1 (HIGH) en utilisant un tableau de correspondance, la deuxième pour mettre à 0 (LOW) et la troisième c'était pour connaître son état après action et ainsi l'intégré dans les infos de retour de la commande (si demandé). 
Bon ici c'était mes débuts sur la plate forme arduino et les µc donc pour certaine choses je ne le ferais peut être pas de la même façon aujourd'hui ...
http://www.mon-club-elec.fr/pmwiki_reference_arduino/pmwiki.php?n=Main.PortManipulation
Pour mieux comprendre le pourquoi.
Sinon tu vas refaire la partie serveur, comme elle n'est sans doute plus valable avec la normalisation actuel ?


Je vous poserai certainement des questions, soit en cas de blocage ou pour valider ma progression !


Yop BriBri,
Concernant la discussion actuel sur le projet websocket à mon avis tu ne sera pas trop concerné comme c'est un projet assé globale mais datant et que j'ai plus ou moin abandonné.
Sinon pas de problème, tes questions sont toujours les bienvenues.  ;)

Brisebee

Bonjour,

J'ai repris tous les programmes et éléments fournis plus haut dans ce post par Osaka , et qui fonctionnent sans problème.

Mon but est de comprendre comment cela fonctionne, pour pouvoir l'adapter ensuite à mon projet de domotique.

J'en profite également pour expliciter la mise en œuvre, ce qui devrait permettre à des débutants comme moi de rentrer plus facilement dans le sujet.

1) Mise en œuvre des programmes fournis par Osaka :

Avec un serveur local sous EasyPHP-5.3.9
(ne pas oublier d'autoriser l'utilisation des sockets)

Mettre dans le répertoire www les programmes suivants :
-   FormRequestAjax.html
-   jquery.min.js
-   socket.php
-   webAjax.js

Charger dans l'Arduino + Ethernet Shield le programme.ino

Ouvrir la fenêtre du Serial Monitor (9600)

Lancer le programme FormRequestAjax.html

Les données remplies dans le formulaire sont transmises à l'Arduino ors de l'appui sur la touche « On », qui les affiche sur le Serial Monitor.

2) Voici ce que j'ai compris du fonctionnement global de ce système :

Le programme FormRequestAjax.html sert d'interface web :
Il fait appel à deux programmes javascript :
-   jquery.min.js : je ne sais pas à quoi cela correspond, j'ai rapidement jeté un œil sur le lien http://api.jquery.com/jQuery.post/ fourni par Osaka, pour l'instant je n'ai pas compris grand chose, mais il va falloir que je m'y intéresse  plus en détail.
-   webAjax.js : qui si j'ai bien compris sert à envoyer les données fournies dans le formulaire lors de l'appui sur la touche « On ».

Le programme socket.php est utilisé dans webAjax.js : je n'ai pas encore compris comment fonctionne les sockets, mais, là aussi, je ne désespère pas.

Le programme .ino qui tourne sur l'Arduino en mode client, reçoit les caractères envoyés par le serveur, les affiche sur le Serial Monitor, et compte le nombre de réquêtes du serveur (d'appuis sur la touche « On »).

N'hésitez pas à corriger mes erreurs et/ou à apporter des informations complémentaires.

@+

nadirovick

#38
Jul 11, 2012, 10:22 pm Last Edit: Jul 11, 2012, 10:28 pm by nadirovick Reason: 1
Salut tt le monde  :)
je suis arrivé à faire fonctionner le serveur avec un nouveau sketch et une trés grande partie du travail d'Osaka  :* ci joint tous les fichers.
tout fonctionne avec WampServer Version 2.2 et IDE 1.0
me reste que la partie état E/S lors du premiere ouverture de la page "onload", je travail dessus
une fois terminée je vais poster le travail

fichier client :

Code: [Select]

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="jquery.min.js"></script>
<script src="init.js"></script>
<!--<script type="text/javascript">
jQuery(function()
    {
        jQuery( "#pwm" ).slider({ max: 255 },{ value: 0 },{step : 5});
   
        jQuery( "#pwm" ).delay(100).bind( "slide", function()
        {
            var value = jQuery( "#pwm" ).slider( "option", "value" );
            analogWrite(0x09, value, 0x00);             
        });
       
        jQuery( "#pwm" ).delay(500).bind( "slidestop", function()
        {
            var value = jQuery( "#pwm" ).slider( "option", "value" );
            analogWrite(0x09, value, 0x01);
        });
   
    });

   </script> -->
   
<style type="text/css">
<!--
.Style1 {font-size: 24px}
.Style2 {font-size: 18px; }
body {
background-color: #FFFFFF;
}
-->
</style>
</head>

<!--<body id="DOMOTIQUE" onload="init()"> -->
<body id="DOMOTIQUE">
<div id="retour"></div>
<div id="retour1"></div>
<div id="retour2"></div>
<div id="retour3"></div>
<div id="log">
  <table width="550" border="0">
    <tr>
      <td width="237" bordercolor="#339999"><div class="Style2">
        <div align="left">LED Sur Pin N°7 :
          <button id="dw7" onclick="digitalWrite(7, 1, 1)">on</button>
        </div>
      </div>
        <div class="Style1">
          <div align="left"><span class="Style2">LED Sur Pin N°8 :</span>
              <button id="dw8" onclick="digitalWrite(8, 1, 1)">on</button>
          </div>
        </div>
        <div></div>      </td>
      <td width="303"><div></div>
        <div></div>      </td>
    </tr>
  </table>
</div>

<div id="pwm"></div>
</body>
</html>


fichier init :

Code: [Select]

function digitalWrite(pin, value, ack)
{
  var textejson = {"str":0x02,"len":0x04, "cmd":0x02, "dt1":pin, "dt2":value, "dt3":ack, "end":0x03 };
  envoie(textejson);
}

function analogRead(pin)
{
  var textejson = {"start":0x02,"length":0x02, "cmd":0x06, "data1":pin, "end":0x03 };
  envoie(textejson);
}

function digitalRead(pin)
{
  var textejson = {"start":0x02,"length":0x02, "cmd":0x03, "data1":pin, "end":0x03 };
  envoie(textejson);
}

function analogWrite(pin, value, ack)
{
  var textejson = {"start":0x02,"length":0x04, "cmd":0x05, "data1":pin, "data2":value, "data3":ack, "end":0x03 };
  envoie(textejson);
}

function envoie(textejson)
{
  jQuery.post("socket.php", textejson,
function(data)
{
parseJSon(JSON.stringify(data));
}, "json");


}
function parseJSon(dJson)
{
  log(dJson);

  var duino = eval('(' + dJson + ')');
  switch(duino.cmd)
  {
    case 0x02:
      digitalWriteResp(duino.data1, duino.data2, duino.data3);
    break;
    case '2':
      digitalWriteResp(duino.data1, duino.data2, duino.data3);
    break;
    case 2:
      digitalWriteResp(duino.data1, duino.data2, duino.data3);
    break;
  }
 
}


function $(id)
{
  return document.getElementById(id);
}

function log(msg)
{
  $("log").innerHTML+="<br>"+msg;
}


function digitalWriteResp(pin, value, ack)
{
    id="dw"+pin;
 
    if(value == 1)
    {
      $(id).innerHTML="off";
      $(id).setAttribute('onclick', "digitalWrite("+pin+", 0, "+ack+")");
    }
    else
    {
      $(id).innerHTML="on";
      $(id).setAttribute('onclick', "digitalWrite("+pin+", 1, "+ack+")");
    }
}


fichier socket :


Code: [Select]
<?php
$msg 
"";
$buffer null;
$msg file_get_contents("php://input"); // on ne reprend que les données utiles et non l'intégralité de la requête 
$host="192.168.1.100";
$port=1080;
$socket socket_create(AF_INETSOCK_STREAMSOL_TCP); //création du socket
socket_connect($socket$host$port); //connection du socket
socket_write($socket,$msg,strlen($msg)); //envoie des données POST
do
{
  if(isset(
$buffer)) // si buffer contien des donnees
echo $buffer// reponse à la requête javascript
//echo json_encode ( $buffer );
}
while(@
socket_recv($socket,$buffer,1024,0) != 0); // on attend la reponse (=! 0) sur le socket
socket_close($socket); //fermeture du socket
?>



Sketch
Code: [Select]
#include <SPI.h>
#include <Ethernet.h>
int i = 0;
char c;
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x14, 0x6D };
byte ip[] = { 192,168,1,100 };
EthernetServer server(1080);
void setup()
{
  for(i = 0; i<=7; i++)
  {
  pinMode(i, OUTPUT);
  }
  Serial.begin(9600);
  Ethernet.begin(mac, ip);
  server.begin();
}
void loop()
{
EthernetClient client = server.available();
if (client)
  {
    if (client.connected())
       {   
         uint8_t lengthData = client.available();
        char data[lengthData];
           int j = 0;
           String affi="";
           while(client.available())
           {
                  c = client.read();
                  affi+=c;
                  j=j+1;
                 
                      switch (j)
                             {
                                case 5:
                                data[0]=c;                 
                                break;
                                case 11:
                                data[1]=c;                 
                                break;
                                case 17:
                                data[2]=c;                 
                                break;
                                case 23:
                                data[3]=c;                 
                                break;
                                case 29:
                                data[4]=c;                 
                                break;
                                case 35:
                                data[5]=c;                 
                                break;
                                case 41:
                                data[6]=c;                 
                                break;                           
                              }}
//Serial.println(affi);
              if(!client.available())
              {   
                if(data[0]== '2' && data[6]=='3')
     {
                 switch (data[2]) {
                                     case '2':
                                     if (data[4]=='1')
                                     {
                                     digitalWrite(data[3], HIGH);
                             }
                                     else
                                     {
                                     digitalWrite(data[3], LOW);
                                     }
                                if(data[0] != '0')
                                   {
                              String json = "{\"start\":";
                                    json+=char(data[0]);
                                    json+=",\"length\":";
                                    json+=char(data[1]);
                              json+=",\"cmd\":";
                                  json+=char(data[2]);
                                   for(int x=0;x < 3; x++)
                                          {
                                                json+=",\"data";
                                              json+=x+1;
                                            json+="\":";
                                              json+=char(data[x+3]);
                                     }                 
                                       json+=",\"end\":";
                                       json+=3;
                                       json+="}";
                               Serial.println(json);//Pour Débogage
                                               client.println(json); // Envoi des données Serveur Web
                                       }
                                        break;
                                   }
     }   
             client.stop();
              }   
}
  }
}


je reste à votre dispositions pour les détails
@+

osaka

Yop Yop,


Le programme FormRequestAjax.html sert d'interface web :
Il fait appel à deux programmes javascript :
-   jquery.min.js : je ne sais pas à quoi cela correspond, j'ai rapidement jeté un œil sur le lien http://api.jquery.com/jQuery.post/ fourni par Osaka, pour l'instant je n'ai pas compris grand chose, mais il va falloir que je m'y intéresse  plus en détail.
-   webAjax.js : qui si j'ai bien compris sert à envoyer les données fournies dans le formulaire lors de l'appui sur la touche « On ».


En fait "jquery.mins.js" c'est une librairie javascript "JQuery", c'est pareil que d'ajouter (#include) la librairie ethernet ou autre dans ton code arduino.
Le fichier "webAjax.js" lui utilise une des fonctions de cette librairie "jQuery.post(...)" qui fabrique (avec les données du formulaire) la requête et l'envoie  à destination de "socket.php" qui lui même se chargera de transmettre ses informations à l'arduino via socket.



Le programme socket.php est utilisé dans webAjax.js : je n'ai pas encore compris comment fonctionne les sockets, mais, là aussi, je ne désespère pas.


les sockets tu peux les comparer au port serie de l'arduino, tu as en premier la création du socket (avec le choix des divers protocoles tcp/ip, udp, ... utilisé dans une communication réseau), ensuite la connections avec les paramètres (ip, port) du destinataire , après ce n'est plus que du read-write sur les données échangées.


Le programme .ino qui tourne sur l'Arduino en mode client, reçoit les caractères envoyés par le serveur, les affiche sur le Serial Monitor, et compte le nombre de réquêtes du serveur (d'appuis sur la touche « On »).


Le programme arduino est plutôt en mode serveur il attend une ou plusieurs connexions socket, les données reçues sont affichés dans le monitor de l'ide ensuite une réponse à la requête est retournée avec le nombre de requête traité par l'arduino. (tu peux fermer ta page formulaire et la relancer, voir même dans un autre navigateur le nb de requête traitée sera définie par l'arduino).
;)

@nadirovick : je te laisse découvrir comme tu as l'air de bien t'en sortir et puis c'est comme ça qu'on apprend.  :smiley-mr-green:

Brisebee

Merci Osaka pour ces précisions.

De mon coté, j'avance tout doucement.

@+

nadirovick

Bonjour  :*,
@ Osaka, oui je sais tu as une longeur d'avance sur moi  :smiley-mr-green:, je cherche à comprendre le problème du Handshake car jusqu'a présent, tout semble fonctionner "je croise les doigts  XD"
je suis un peux occupé cette semaine, beaucoup de boulot
n'empêche que je jeterai un coup d'oeil de temp à autre
@+

archibal11

Bonjour a tous,

Nadirovick  pourrai tu s'il te plait m'expliquer le fonctionnement  de  jQuery(function(),je n'arrive pas a décrypter le code,merci.

Code: [Select]
jQuery(function()
    {
        jQuery( "#pwm" ).slider({ max: 255 },{ value: 0 },{step : 5});
   
        jQuery( "#pwm" ).delay(100).bind( "slide", function()
        {
            var value = jQuery( "#pwm" ).slider( "option", "value" );
            analogWrite(0x09, value, 0x00);             
        });
       
        jQuery( "#pwm" ).delay(500).bind( "slidestop", function()
        {
            var value = jQuery( "#pwm" ).slider( "option", "value" );
            analogWrite(0x09, value, 0x01);
        });
   
    });



osaka

#43
Jul 15, 2012, 07:00 pm Last Edit: Jul 15, 2012, 08:25 pm by osaka Reason: 1

je cherche à comprendre le problème du Handshake car jusqu'a présent, tout semble fonctionner "je croise les doigts  XD"


Tu as testé la version websocket ou juste les simple requêtes http comme tu l'as mis plus haut ?  :smiley-mr-green:


Code: [Select]
jQuery(function()
   {
       jQuery( "#pwm" ).slider({ max: 255 },{ value: 0 },{step : 5}); //création du slider sur la balise id="pwm"
                                                                      //sa valeur maximum sera de 255
                                                                      //la valeur 0 par défaut au lancement de la page
                                                                      //pas minimum de valeur 5 entre deux déplacements du slider
   
       jQuery( "#pwm" ).delay(100).bind( "slide", function() //la fonction sera appelé à chaque déplacement du slider(delay de 100ms mini entre deux appels)
       {
           var value = jQuery( "#pwm" ).slider( "option", "value" ); //on récupère la valeur actuel du slider
           analogWrite(0x09, value, 0x00); //appel de la fonction analogWrite avec en param. la valeur (value) actuel du slider (0x00 pas de ack demandé pour une question de perf entre deux requêtes)        
       });
       
       jQuery( "#pwm" ).delay(500).bind( "slidestop", function() //au relâchement (souris) du slider (delay mini de 500 entre deux appel de la fonction)
       {
           var value = jQuery( "#pwm" ).slider( "option", "value" ); //on récupère la valeur actuel du slider
            analogWrite(0x09, value, 0x01); //appel de la fonction analogWrite avec en param. la valeur (value) actuel du slider  (0x01 ack demandé)
       });
   
   });



Toute les options.
http://docs.jquery.com/UI/Slider

Edit: avait oublier de mettre le lien  :smiley-sweat:

archibal11

Merci Osaka pour les commentaires de cette fonction, j'y vois plus clair..

Grâce a ton travail j'ai réussi a monter un serveur web et commander des lampes par l'intermédiaire d'un module 433 mhz , reste a l'améliorer graphiquement..
Par la suite je rajouterai des affichages des températures et taux d'humidité; je ne sais pas encore comment m'y prendre pour afficher les infos en temps réel , peut etre utilisé une BDD sql ou autre;  si tu as un conseil a me donner je suit preneur.
Mais pour l'instant je vais recodé mes programmes pour reprendre ton principe de trame que je trouve très intéressante ..
{"str":0x02,"len":0x04, "cmd":0x02, "dt1":pin, "dt2":value, "dt3":ack, "end":0x03 };

Merci et bonne continuation ...

Go Up