python ethernet et histoire de socket

Bonjour
Maintenant que je reussi faire mon ping j’essai de recevoir des infos du module arduino.
Je réussi a récupérer les infos sur une page web connecté sur l’adresse ip du shield ethernet
mais je ne réussi pas a récupérer via un script python très simple…
Au lancement du script il attend sans erreur mais ne reçoit rien
J’ai essayé de mettre des traces et il semble que le Arduino ne rentre pas dans la boucle “If client” avec le script python alors qu’avec la page web il rentre…

Si vous avez des idées ?

Merci

Script python :

#! /usr/bin/env python
# -*- coding: iso-8859-1 -*-

import socket

Host = '192.168.0.60'
Port = 80
 
Sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Sock.connect((Host, Port))

data = Sock.recv(255)
print data 

Sock.close()

Et le prog Arduino pour info (même si il marche sur une page web) :

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


/* Détails technique de la connexion ethernet */
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x56, 0xB3 };  
byte ip[] = { 192, 168, 0, 60 };
byte gateway[] = { 192, 168, 0, 254 };
byte subnet[] = { 255, 255, 255, 0 }; 
EthernetServer serveurHTTP(80); 
  
void setup() {
  pinMode(dhtPin, INPUT);
  
    // Configuration de la ethernet shield et du server
  Ethernet.begin(mac, ip, gateway, subnet);
  delay(1000); // donne le temps à la carte Ethernet de s'initialiser
  serveurHTTP.begin(); 
}

void loop() {
  
// recuperation d'un capteur des valeurs de humidité et temperature .... (retiré pour le na encombrer le prog)

  EthernetClient client = serveurHTTP.available();

  if (client) { 
 
    if (client.connected()) {
      
          client.print("Current humdity = ");
          client.print(humidity,1);
          client.print("%  ");
          client.print("temperature = ");
          client.print(temperature,1);
          client.println("C  ");
  
    } // --- fin if client connected
  
    delay(1);  // on donne au navigateur le temps de recevoir les données

  client.stop(); // ferme le client distant une fois réponse envoyée
  delay(10);     // laisse temps fermeture

  }   
}

bonjour, un peu d'aide avec ca http://wiki.python.org/moin/UdpCommunication

Super merci Je potasse et je vois si je comprend tout. Juste une question, l'arduino il est en tcp ou udp (car j'avais cru lire que comme fait dans mon exemple c'était du tcp

Bonjour,

ewok2: Juste une question, l'arduino il est en tcp ou udp (car j'avais cru lire que comme fait dans mon exemple c'était du tcp

TCP de base, UDP si tu lui demande en utilisant la classe EthernetUDP.

Et ça à un intérêt de passer en UDP? J'avais cru comprendre que pour des courtes distances (réseau local) la correction d'erreur n.etait plus nécessaire maintenant?

Outre la notion de correction d'erreur il faut aussi prendre en compte le fonctionnement même d'udp et de tcp. UDP -> datagrammes, ils peuvent arriver (ou non) dans n'importe quel ordre TCP -> flux, les paquets arrivent forcément (acquittement) et dans le même ordre qu'as l'envoi.

En gros UDP c'est le bourrin, TCP c'est la sécurité.

Donc mieux vaut faire du top vu que c'est le par défaut arduino ;-)

Si j'ai bien compris, tu souhaites envoyer les données de température à un client python connecté sur le serveur TCP lancé sur ton Arduino. Il faudrait que tu ajoutes des gestions d'erreur autant sur le client que sur le serveur et des logs associés pour savoir où ça passe pas.

Mais à la rigueur essaie de faire l'inverse, c'est à dire d'avoir un serveur qui tourne sur le PC en attente de connexion et le Arduino qui s'y connecte et qui lui envoi la température. Voir même temps qu'a faire de monter un serveur WebSocket, de s'y connecter avec le arduino au démarrage et de lui envoyer régulièrement la température qui pourra être réplique vers les navigateurs Web connectés en temps réel.

bon j’ai trouvé une methode qui marche

#! /usr/bin/env python
# -*- coding: iso-8859-1 -*-

import time
import httplib

Host = '192.168.0.60'
i = 1

while (i < 20):
   conn = httplib.HTTPConnection(Host)
   conn.request("GET", "/index.html")
   r1 = conn.getresponse()
   print r1.read()
   i = i+1
   conn.close()
   time.sleep(1)

mais c’est pas super quand meme.
Je recoit du texte donc je pourai le spliter et recuperer ce qui m’interesse mais c’est intelectuellement pas satisfaisant…

tonyryu ton poste m’aleche peux tu developper un peu que je cherche dans cette direction…

Merci

Ton problème vient surtout du fait, que du coté serveur Arduino, tu ouvre un socket en écoute sans protocole, et que du coté client Python, tu ouvres une connexion au protocole HTTP. Ca a forcément du mal à discuter.

Il faut que tu te connectes au serveur Arduino, avec un socket client simple sans passer par une surcouche HTTP. Une fois connecté sur le serveur, il faut que ton client se mette en attente de trame provenant du serveur. Et coté serveur Arduino, dès qu'il détecte un client connecté, il envoi un trame simple du genre :

TMPHUM|[valeur température]|[valeur humidité]

Ce qui pourrait te donner

TMPHUM|19,4|64

Il suffit ensuite d'extraire les données de la trame via ton client python et de les afficher comme tu veux.

--------- Détail de ma solution en cours de développement -------------

Nous sommes actuellement entrain de mettre en place un sytème, permettant d'ajouter un contrôle des dispositifs de la maison via une page Web. Pour cela j'ai récupéré et modifier un code serveur webSocket PHP, une librairie WebSocketClient pour le arduino.

Le serveur PhP est hébergé sur un serveur applicatif dans la maison qui est controlé. Chaque Arduino Ethernet contrôle une pièce. Dans le code du Arduino, une variable définit la salle qu'il contrôle, et un tableau de structure définit les dispositifs et les actions à réaliser en cas de déclenchement. A chaque boucle, si le arduino est connecté au WebSocket, il récupère la dernière trame du serveur et vérifie si il s'agit d'une commande de déclenchement d'un dispositif, si c'est le cas, il exécute l'action paramétrée. Dans le cas où le Arduino ne serait pas connecté au serveur il tente de se reconnecter, en cas d'echec, il retentera 10 sec plus tard. Les déclenchements peuvent également se faire via une entré paramétré sur le Arduino. Pour chaque action réalisée, soit manuelle ou demandée par le serveur, le arduino envoi au serveur l'état du dispositif déclenché.

J'ai également développement un petit site Web de test, qui se connecte également sur le serveur WebSocket, ce qui a le gros avantage d'avoir le changement d'état des dispositifs en temps réel sur la page web sans action de la personne consultant le site. Et l'on peut également y commander les dispositif, en temps réel.

Nous attendons de recevoir les thermistance pour implémenter la partie de contrôle des températures des pièces. Mais le principe est le même, il suffira d'ajouter un dispositif, dont le déclenchement se fera selon une fréquence (5 min par exemple), et l'action sera un relevé de la température qui sera envoyé au serveur, et répliqué vers les site Web connecté.

Je ferais un topic plus détaillé quant on aura un peu plus avancer dans nos développement. Mais toute la partie si dessus et déjà testé et validé.

Ca m’intéresse bien ta solution, dis moi des que tu publie quelque chose ;-)

Sinon je comprend pas pourquoi tu dis :

que du coté serveur Arduino, tu ouvre un socket en écoute sans protocole

Sauf erreur l'arduino est declaré HTTP "EthernetServer serveurHTTP(80); " ?

Je pensai plutot (en attendant ta solution) rester sur une comunication HTTP pour en plus de python recuperer ces info sur une page Web (en static bien sur). Mais faire un systeme d'intergogation : - Le python envoi une requete 'temperature' et l'arduino repond avec la valeur du capteur...

non, c'est juste que tu nommes ton objet de classe EthernetServer, "serveurHTTP", mais la classe EthernetServer n'est pas du tout un serveur HTTP.

Interresse-toi a comment fonctionne les sockets de base, avant d'aller plus loin, quite a faire un client et un serveur avec des langages simples sur ton ordinateur pour voir comment cela fonctionne.