Page 4 sur 53

Re: Tous les capteurs reliés au RPI par Wifi avec module ESP

Posté : lun. 23 févr. 2015 15:31
par Jean-Marie
Hello Veloce et Philippe,

Merci Plilippe pour le lien d'aide supplémentaire.
Voilà, j'ai courageusement commencé mes 95 pages.

A la page 4, j'ai déjà appris qu'on allait parler essentiellement de deux types de sockets : One is “Stream Sockets”; the other is “Datagram
Sockets”, which may hereafter be referred to as “SOCK_STREAM” and “SOCK_DGRAM”, respectively.


et un peu plus loin, j'ai eu le plaisir de lire : you may have heard of the telnet application, yes? It uses stream sockets.

Il semblerait donc qu'on soit dans le bon. Avec un peu de chance, les eaux dans lesquelles on navigue vont devenir limpides. Si c'est le cas, je me ferai un plaisir de remplir le point N°5 de Veloce car c'est le meilleur moyen d'avoir moi-même les idées claires.

Re: Tous les capteurs reliés au RPI par Wifi avec module ESP

Posté : mar. 24 févr. 2015 10:21
par smba38
On peut facilement réaliser un serveur Web avec un module ESP8266.
J'utilise la carte de développement Nodemcu ( Un dizaine d'euros).
http://www.electrodragon.com/product/es ... ent-board/
Cette carte est à base de ESP-12 et elle dispose d'une entrée ADC.
Cette carte se programme en Lua, langage orienté réseau.
J'ai réalisé un petit serveur WEB qui permet de visualiser les valeurs d'un capteur MQ3 (éthylomètre).
Le programme utilise un cinquantaine de lignes de code (une grande partie du code est pour générer la page HTML).
Lua dispose de modules GPIO, PWM, I2C, ADC, SPI, Onewire.

SMBA38

Re: Tous les capteurs reliés au RPI par Wifi avec module ESP

Posté : mar. 24 févr. 2015 20:41
par smba38
Utilisation d’une puce ESP8266 avec le kit de développement nodemcu..
Voici quelques informations sur ce kit : https://github.com/nodemcu
Et http://www.electrodragon.com/product/es ... ent-board/

Pour utiliser le langage Lua (langage orienté réseau) du kit de développement nodemcu (ou d’une puce ESP-XX) il faut :
Flasher le firmware de l’Esp8266 avec le Flasher : https://github.com/nodemcu/nodemcu-flasher
Télécharger la release 32 ou 64 bits (sous Windows, pour linux il existe un programme python esptool.py).
Un firmware est contenu dans l’exécutable, choisir le port, cliquer sur Flash, appuyer sur le bouton Flash du Kit.
le flasher peut également flasher un firmware à partir d'un fichier binaire .bin
Pour avoir le dernier firmware http://bbs.nodemcu.com/t/nodemcusan-xiao-shi-ru-men/104
Il faut décocher dans l’onglet Config du flasher toutes les lignes INTERNAL et ajouter le PATH du firmware (Avec un Offset=0)

En se connectant sur le port de COM à 9600 bauds 8N1 on a accès à l’interpréteur Lua .

Code : Tout sélectionner

> ŠHlèˆbEC[1A]ù<C[0F]$dñlb<l¬ñ[07]yI[08]€[00]àø
NodeMCU 0.9.5 build 20150213  powered by Lua 5.1.4
> 
Attention au reboot de l’ESP8266 des caractères bizarres sont affichés à 74880 bauds ?.

Via le port série on injecte des programmes lua , ces programmes sont conservés en mémoire flash sous forme de fichiers au format spiffs .

La puce ESP8266 peut être configurée en point d’accès WIFI, en station ou les deux à la fois.
Par défaut l’adresse IP du point d’accès est 192.168.4.1 (IP non modifiable).

On peut programmer facilement des serveurs http, telnet, des sockets , des capteurs (I2C,SPI,Onewire,PWM,ADC), il existe également le protocole MQTT (machine to machine).
Avec un ESP-XX configuré en serveur telnet on peut accéder à distance à l’interpréteur lua.
Une fois programmée la puce ESP8266 peut être autonome, il suffit d’ajouter une alimentation.

Il existe plusieurs modules ESP-XX, pour avoir une entrée ADC il faut un module ESP-12.
Le kit nodemcu dispose d’un module ESP-12.
Les modules ESP-XX diffèrent par le nombre de GPIO, la forme de l’antenne (PCB, céramique, pas d’antenne ) , la mémoire flash, la protection contre les interférences.
http://l0l.org.uk/2014/12/esp8266-modul ... ch-em-all/

Pour limiter la consummation on peut mettre en veille l’ESP8266 par -> node.dsleep().
Au reveil l’esp8266 effectue un reboot.
Pour la liste des Api :
https://github.com/nodemcu/nodemcu-firm ... nstruction


Pour gérer les fichiers de la mémoire flash, on peut utiliser un des programmes :
NodeMcu studio: http://bbs.nodemcu.com/uploads/default/ ... 6986d8.rar
Le programme java: http://esp8266.ru/esplorer/

Le fichier init.lua est lancé automatiquement au boot.
On peut compiler un fichier Lua ->node.compile(“init.lua”) va créer un fichier bytecode “init.lc” dans la mémoire flash.

Voici un exemple de programme lua qui liste les noms des fichiers contenus dans la mémoire Flash.
Pour enregistrer un programme en mémoire, on utilise le module File.
Pour executer un programme: dofile(“xx.lua”)

Code : Tout sélectionner

> file.remove("list.lua")
> file.open("list.lua","w+")
> file.writeline("l = file.list();")
> file.writeline("    for k,v in pairs(l) do")
> file.writeline("      print(\"name:\"..k..\", size:\"..v)")
> file.writeline("    end")
> file.close()

> dofile("list.lua")

name:init.lua, size:2698
name:myfile.lua, size:234
name:list.lua, size:90
name:init - Copie.lua, size:1456
name:init.lc, size:3232
>
-- a simple http server

Code : Tout sélectionner

srv=net.createServer(net.TCP) 
srv:listen(80,function(conn) 
    conn:on("receive",function(conn,payload) 
    print(payload) 
    conn:send("<h1> Hello, NodeMcu.</h1>")
    end) 
end)
Quelques exemples de programmes en lua : http://nodemcu.com/index_en.html#fr_547 ... 501100000f

La suite au prochain numéro.

Re: Tous les capteurs reliés au RPI par Wifi avec module ESP

Posté : mar. 24 févr. 2015 23:12
par Jean-Marie
hello smba38

Un grand merci pour ta contribution.

Je n'avais pas vu ton dernier message et j'étais en train de répondre à ton premier message en parcourant les sites et en notant l'une ou l'autre des références que tu as mises. J'ai donc tout effacé car tu es beaucoup plus complet que ce que j'avais trouvé.

Tu sembles très au courant de ces modules ESP. Lua semble beaucoup plus puissant que le simple langage des commandes AT.
Dans ma lecture sur les sockets, je n'en suis qu'à la page 13 (sur 95). Je suis empêtré dans des structures incluses dans d'autres structures, faisant à nouveau partie de structures. Pour couronner tout cela, on peut faire par endroit du typecasting. Autant dire que pour un débutant en C, c'est pas du gâteau !!!
Mais j'ignore si les choses seraient plus simples en Lua.

Je suis à l'écoute des avis.

Re: Tous les capteurs reliés au RPI par Wifi avec module ESP

Posté : mer. 25 févr. 2015 00:09
par smba38
Bonsoir Jean-Marie.

Pour moi le langage lua me semble convenir si:

On n'a pas besoin de puissance de calcul ( Lua est un langage interprété).
Que l'on veut utiliser l'ESP8266 en autonome (avec un capteur et une pile).
Que quelques secondes toutes les n minutes suffisent au traitement que l'on doit effectuer ( pour limiter le consommation).
Que le projet ne soit pas trop gourmand en mémoire vive (RAM).
Il suffit de peu de lignes de code pour gérer des fichiers dans la mémoire flash.

Ensuite ça dépend de ce que tu veux faire et de quelle façon tu veux dialoguer avec l'Esp8266 ( Sockets, HTTP, Telnet .. ).

On peut à la place de Lua utiliser un programme en C pour avoir plus de rapidité.

Espressif la boîte qui fabrique la puce ESP8266 propose une machine virtuelle (sous virtualbox) avec un environnement de développement tout préparé, je l'ai testé est c'est assez facile de de recompiler des exemples fournis.
https://drive.google.com/folderview?id= ... sp=sharing

Le plus difficile est d'exploiter les données fournies par les capteurs connectés à l'Esp8266.

On peut par exemple utiliser un Raspberry avec apache comme serveur Web, MySQL comme base de données, et PHP comme langage de programmation.

Pour conclure, il faut définir:

Quels capteurs seront utilisés.
Quelle est la fréquence d'envoi des données au serveur.
Quel sera le protocole d'échange.
Comment les données seront stockées et traitées sur le serveur.

On rentre dans le domaine de l'internet des objets.

On peut se simplifier le travail, car on peut par exemple utiliser un serveur Web prévu pour stocker ce genre de données.

par exemple la base ThingSpeak https://thingspeak.com/(

Il faut créer un compte chez ThingSpeak (c'est gratuit).
Une clef d’écriture est générée cette clef est associée à un canal (channel).
Ces informations permettent de s'identifier sur la base thingspeak
par exemple pour stocker des données sur les températures lues par un capteur de température dth11
Modifier le fichier exemple dth11.lua

Code : Tout sélectionner

-- Measure temperature, humidity and post data to thingspeak.com 
-- 2014 OK1CDJ 
-- DHT11 code is from esp8266.com 
---Sensor DHT11 is conntected to GPIO2 pin= 4  sur sdk >  2015,  9 avant 
pin =4
 
Humidity = 0 
HumidityDec=0 
Temperature = 0 
TemperatureDec=0 
Checksum = 0 
ChecksumTest=0 
Nb=0
  
function getTemp() 
Humidity = 0 
HumidityDec=0 
Temperature = 0 
TemperatureDec=0 
Checksum = 0 
ChecksumTest=0 

--Data stream acquisition timing is critical. There's 
--barely enough speed to work with to make this happen. 
--Pre-allocate vars used in loop. 
 
bitStream = {} 
for j = 1, 40, 1 do 
     bitStream[j]=0 
end 
bitlength=0 

 
gpio.mode(pin, gpio.OUTPUT) 
gpio.write(pin, gpio.LOW) 
tmr.delay(20000) 
--Use Markus Gritsch trick to speed up read/write on GPIO 
gpio_read=gpio.read 
gpio_write=gpio.write 
 
gpio.mode(pin, gpio.INPUT) 
 
--bus will always let up eventually, don't bother with timeout 
while (gpio_read(pin)==0 ) do end 
 
c=0 
while (gpio_read(pin)==1 and c<100) do c=c+1 end 
 
--bus will always let up eventually, don't bother with timeout 
while (gpio_read(pin)==0 ) do end 
 
c=0 
while (gpio_read(pin)==1 and c<100) do c=c+1 end 
--acquisition loop 
for j = 1, 40, 1 do 
     while (gpio_read(pin)==1 and bitlength<10 ) do 
          bitlength=bitlength+1 
     end 
     bitStream[j]=bitlength 
     bitlength=0 
     --bus will always let up eventually, don't bother with timeout 
     while (gpio_read(pin)==0) do end 
end 

--DHT data acquired, process. 
 
for i = 1, 8, 1 do 
     if (bitStream[i+0] > 2) then 
          Humidity = Humidity+2^(8-i) 
     end 
end 
for i = 1, 8, 1 do 
     if (bitStream[i+8] > 2) then 
          HumidityDec = HumidityDec+2^(8-i) 
     end 
end 
for i = 1, 8, 1 do 
     if (bitStream[i+16] > 2) then 
          Temperature = Temperature+2^(8-i) 
     end 
end 
for i = 1, 8, 1 do 
     if (bitStream[i+24] > 2) then 
          TemperatureDec = TemperatureDec+2^(8-i) 
     end 
end 
for i = 1, 8, 1 do 
     if (bitStream[i+32] > 2) then 
          Checksum = Checksum+2^(8-i) 
     end 
end 
ChecksumTest=(Humidity+HumidityDec+Temperature+TemperatureDec) % 0xFF 

print ("Nb="..Nb) 
print ("Temperature: "..Temperature.."."..TemperatureDec) 
print ("Humidity: "..Humidity.."."..HumidityDec) 
print ("ChecksumReceived: "..Checksum) 
print ("ChecksumTest: "..ChecksumTest) 
end 
 
--- Get temp and send data to thingspeak.com 
function sendData()
Nb=Nb+1 
getTemp() 
-- conection to thingspeak.com 
print("Sending data to thingspeak.com") 
conn=net.createConnection(net.TCP, 0)  
conn:on("receive", function(conn, payload) print(payload) end) 
-- api.thingspeak.com 184.106.153.149 
conn:connect(80,'184.106.153.149')  
-- key J7ITU7P95C6XXXXXX 
conn:send("GET /update?key=J7ITU7P95XXXXXXXR&field1="..Temperature.."."..TemperatureDec.."&field2="..Humidity.."."..HumidityDec.." HTTP/1.1\r\n")  
conn:send("Host: api.thingspeak.com\r\n")  
conn:send("Accept: */*\r\n")  
conn:send("User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n") 
conn:send("\r\n") 
conn:on("sent",function(conn) 
                      print("Closing connection") 
                      conn:close() 
                  end) 
conn:on("disconnection", function(conn) 
                      print("Got disconnection...") 
  end) 
end 
-- première fois pb sur première lecture
sendData()
tmr.delay(2000000)
-- getTemp()
-- send data every X ms to thing speak 
tmr.alarm(2, 600000, 1, function() sendData() end ) 
les données de la base peuvent être privées ou publiques.
Il y a un forum sur http://community.thingspeak.com/forum/esp8266-wi-fi/
qui cause de l'ESP8266.
Bonne lecture
SMBA38.

Re: Tous les capteurs reliés au RPI par Wifi avec module ESP

Posté : mer. 25 févr. 2015 22:32
par Jean-Marie
Hello smba38,
Pour moi le langage lua me semble convenir si:
  • On n'a pas besoin de puissance de calcul ( Lua est un langage interprété)
.
Si on veut se servir des modules ESP pour connecter des capteurs ou des effecteurs. Il n'y a guère de calculs à faire. Si un capteur donne une valeur digitale, on peut la transmettre telle quelle. Si c'est une valeur analogique, l'ESP peut utiliser sa pin ADC pour la convertir avant l'envoi.
  • Que l'on veut utiliser l'ESP8266 en autonome (avec un capteur et une pile).
Utiliser l'ESP en autonome seulement avec son capteur est une possibilité (si c'est facile), mais pas une obligation. Il y a quelques jours, j'ai commandé 10 ATtiny85 chez AliExpress pour moins de 8€, envoi compris. Donc, si l'ajout d'un ATtiny peut rendre l'utilisation plus facile, le coût n'est vraiment pas un obstacle.
  • Que quelques secondes toutes les n minutes suffisent au traitement que l'on doit effectuer ( pour limiter le consommation).
Dans l'utilisation que j'envisage (quelques capteurs de T°et de lumière, éventuellement d'humidité de sol des plantes) une mesure toutes les 15 ou 30 min serait sans doute largement suffisante. Le reste du temps, le matériel peut entrer en deep sleep.
  • Que le projet ne soit pas trop gourmand en mémoire vive (RAM).
Quelques octets seraient suffisants pour décompter le temps restant du "sleep" et pour contenir le résultat de la mesure.
  • ça dépend de ce que tu veux faire et de quelle façon tu veux dialoguer avec l'Esp8266 ( Sockets, HTTP, Telnet .. ).
Je vois que ce n'est pas très compliqué de demander au ESP d'envoyer des données sur une page à afficher avec un Browser Internet, que ce soit en local ou à distance comme Thinkspeak. Ces données peuvent être envoyées soit par un programme Lua commandant l'ESP de l'intérieur, soit par des commandes AT provenant d'un microcontrôleur externe.
A ce niveau, j'aurais d'ailleurs une première question : si on flashe le "NodeMCU" dans le module, a-t-on toujours accès aux commandes AT habituelles ? Autrement dit, peut-on encore choisir entre Lua et un µC externe ?

Mais la grosse question que je me pose depuis le début de ce thread est la suivante. Les tutoriaux montrent toujours comment envoyer des caractères ascii à une adresse IP, en particulier avec la commande AT+CIPSEND. Mais comment reçevoir ces caractères dans une ou plusieurs variables à l'intérieur d'un programme du PC ou de l'unité centrale ???
Et comment envisager les transferts en sens inverse : de l'unité centrale vers le module ESP périphérique ???
Je n'y vois pas clair.

Re: Tous les capteurs reliés au RPI par Wifi avec module ESP

Posté : mer. 25 févr. 2015 23:14
par smba38
Bonsoir Jean-Marie.

Si l'on utilise lua, on ne dispose plus des commandes AT.
Il est préférable d'utiliser lua en mode autonome car l'intelligence est dans le code lua.

Pour récupérer les données envoyées par l'ESP8266 plusieurs cas:

On récupère les données et on les traites ensuite en différé.
On veut traiter les données en temps réel quand elles arrivent dans ce cas, il faut programmer.
On ne peut pas se permettre de perdre des données.

On peut par exemple utiliser le langage python à travers des sockets.

Voici plusieurs exemples de communications.

Avec les commandes at:
dans les exemples suivant on utilise la commande nc (netcat) sous Windows ou sous linux pour écouter sur un port.
On peut en python écouter sur un port et faire des traitements en temps réel.

La difficulté est de prévoir les cas ou les connexions sont fermées.

Code : Tout sélectionner

AT
OK
AT+GMR
00200.9.5(b1) -> sdk 20 firmware 9.5
compiled @ Dec 25 2014 21:40:28

AT+CWMODE?  -> ? Utilisé pour interroger une valeur 
+CWMODE:3      -> 1=STA 2=AP 3=STA+AP

AT+CWMODE=3 -> = utilisé pour modifier une valeur
OK

AT+CWLAP  -> points d’accès à portée
+CWLAP:(3,"WRT54G_409B",-59,"00:12:17:b3:40:9d",1)
+CWLAP:(4,"larivoire234",-82,"34:8a:ae:3c:cc:44",6)


AT+CWJAP="WRT54G_409B","23423423423423423423423423" -> connexion au routeur WRT54G_409B
OK

On peut configure l’AP  (nom, pwd, authentification, sauf l’adresse IP qui est par défaut 192.168.4.1)
Par défaut pas de mot de passe et le nom du point d’accès est xxx_yyyy (YYY= fin adresse MAC du point d’accès).
AT+CWSAP="ESP8266","00000000",4,3 -> SSID, pwd,canal, authentification 1=WEP,2=WPA,3=WPA2,4=WPA+WPA2

AT+CIFSR -> Infos connexions 
+CIFSR:APIP,"192.168.4.1" 		 -> AP (Acces point) IP non modifiable par commandes AT
+CIFSR:APMAC,"1a:fe:34:9b:c8:31"
+CIFSR:STAIP,"192.168.1.17"		-> IP affectée par le DHCP du routeur WRT54G_409B
+CIFSR:STAMAC,"18:fe:34:9b:c8:31"
OK

Après connexion en WIFI au point d’accès 192.168.4.1 depuis un PC 
AT+CWLIF
192.168.4.101   f8:4e:06:1c:f2:b7  -> Adresse IP affectée par le DHCP du point d’accès 192.168.4.1

Dans une console sur un PC le ping répond  sur 192.168.1.17 ou 192.168.4.101
Réponse de 192.168.1.17 : octets=32 temps=4 ms TTL=255

AT+CIPMUX=1  ->multi connexions
OK
Sur le pc d’adresse IP 192.168.1.30 lancer la commande netcat pour écouter sur l’IP 192.168.1.17 port 4444
nc -l 192.168.1.17 -p 4444

AT+CIPSTART=0,"TCP","192.168.1.30",4444 -> connexion au PC d’adresse IP 192.168.1.30 sur le port 4444
0,CONNECT
OK

AT+CIPSEND=0,5 -> envoi sur canal 0, sur 5 octets
> aaaaa
SEND OK

Il existe des firmwares modifiés par exemple pour gérer les GPIO via des commandes AT http://www.electrodragon.com/w/ESP8266_Custom_AT_Firmware
AT + CIOADC command reads the ADC value Note: ADC input voltage 0,1V  0 to 1024,10 bit precision
AT + CIOREAD command reads the GPIO AT + CIOREAD = 0 reads GPIO0 level return 1 , 0 
AT + CIOWRITE command to set the GPIO AT + CIOWRITE = 0,0 setting GPIO0 level is low 
AT + CIOWRITE = 16,1 set of high level GPIO16
Je viens de tester un solution d'envoi de données par mail directement depuis lua.
Cette solution à l'avantage de régler les cas ou le serveur qui écoute les esp8266 est hors fonction.

Pour comprendre le protocole utilisé par un serveur de mails SMTP (mails sortants)
On peut simplement utiliser un client telnet sur le port 25
Et répondre aux messages du serveur SMTP.
Ne pas oublier le point (.) en fin de message.
Par exemple depuis une ligne de commande CMD sous Windows (sous linux c’est le même principe).

Code : Tout sélectionner

telnet smtp.orange.fr 25
220 mwinf5d23 ME ESMTP server ready
HELO orange.fr
250 mwinf5d23 hello [90.15.24.192], pleased to meet you
MAIL FROM: <SMBA38.esp8266@orange.fr>
250 2.1.0 <SMBA38.esp8266@orange.fr fr 
> sender ok
RCPT TO: <esp8266.michel@orange.fr>
250 2.1.5 <esp8266.michel@orange.fr> recipient ok
DATA
354 enter mail, end with "." on a line by itself
Reply-to: <SMBA38.esp8266@orange.fr>
Subject: test envoi mail par esp8266
Et en plus ça fonctionne
C’est super 
SMBA38 
.
250 2.0.0 wYzq1p00Q48gNr603Z0e5d mail accepted for delivery
QUIT
221 2.0.0 mwinf5d23 ME closing connection
Perte de la connexion à l'hôte.
Et bien sur on peut faire la même chose en LUA

Infos récupérées sur http://www.esp8266.com/viewtopic.php?f=24&t=1231

Le programme utilise une table d’états step[].
A chacune des 8 étapes le code renvoyé par le serveur SMTP doit être correct pour passer à l’état suivant.
A la fin de l’envoi d’un mail on peut choisir de ne pas quitter le programme, de rebooter
Ou de se mettre en veille « node.dsleep() » (mais il faut PIN32(RST) et PIN8(XPD_DCDC) reliées).
En fin de veille, l’esp8266 effectue un reboot.
Le Reboot est conseillé car le ramasse miettes « collectgarbage() » ne semble pas sur et le second mail n’est pas envoyé , mais le troisième est envoyé ? ( A creuser).
Il faut modifier l’avant dernière ligne du code pour indiquer :
les adresses mails de l’émetteur, du récepteur, le sujet le corps du mail et le serveur SMTP.

Code : Tout sélectionner

-- Fonction d'envoi d'un mail   (sur une idée de http://www.esp8266.com/viewtopic.php?f=24&t=1231)
-- avec le traitements des Evenements associés à la vie de la connexion TCP
-- le traitement du mail comporte 8 étapes enchainées au fur et à mesure des réponses du serveur SMTP
-- A chaque étape "handle_response est appelé"
-- Problèmes a voir: pas de "de" dans les messages reçus, pas d'envoi au second appel de send mail.
-- Idées d’améliorations : création fichier log des alertes envoyé en pièce jointe
-- + Récupération  de la date sur un serveur NTP.

sendmail=function(from,to,subject,body,server)
-- reponses au message reçus du serveur SMTP 
   local handle_response = function(conn,response,step,state) 
      --print("handling state:" .. state  .. "Heap=" .. node.heap() .. "expecting:" .. step[state].expected  .. " got:" .. response)
      if response:match(step[state].expected )
      then  -- c'est le code attendu du serveur SMTP
          print ("(" .. state ..") OK")
         if step[state].request  -- il existe un request dans la table 
         then
            conn:send(step[state].request .. "\r\n")  -- envoi contenu message request au serveur SMTP
         else
            conn:close()   -- pas de request dans la table step[state], on ferme la connexion 
         end
         state = state + 1  -- on passe à l'état suivant
     else
         conn:close()  -- la réponse attendue n'est pas la bonne on ferme la connexion
      end
      return(state)  -- Etat en cours en retour
   end
-- gestion des états 
   local step={}
   local smtp_server,smtp_port
   smtp_server,smtp_port = server:match("(.*):(.*)")
   local domain=from:match("@(.*)$")
-- table des états de connexion
   step[1]={expected="^220",request="HELO " .. domain}
   step[2]={expected="^250",request="MAIL FROM: <" .. from ..">"} -- from
   step[3]={expected="^250",request="RCPT TO: <" .. to .. ">"}  -- to
   step[4]={expected="^250",request="DATA"}   -- données
   step[5]={expected="^354"} -- SMTP pret à recevoir des données
-- A addapter en fonction des serveurs de mail  on peut utiliser: To:,  From:,   Reply-to, …
-- A tester pour que le mail ne soit pas considéré comme un Spam.   
-- le From peut être différent du MAIL FROM: (c'est l'adresse mail de retour).
  step[5].request =string.format("From:<%s>\r\nSubject:%s\r\n\r\n%s\r\n.",from,subject,body)
   step[6]={expected="^250",request = "QUIT"} -- headers/message
   step[7]={expected="^221"}  -- quit
-- step[8] se produit sur Evenement "disconnection"

-- création connexion TCP   et traitement des Evenements conn:on("evenement", ...)
   local conn=net.createConnection(net.TCP, false) 
   local state=0
-- Réponses aux Evenements    conn:on 
  conn:on("connection", function(conn)                     -- Evenement connexion OK 
      print("connected") 
      state = 1  
      end )                                                    
                                       
   conn:on("receive", function(conn, payload)            -- Evenement : un message vient d'arriver 
      --print("received:" .. payload)                            -- log du message
      state=handle_response(conn,payload,step,state) -- réponse au message envoyé par SMTP
   end )
   conn:on("sent", function(conn)                              -- Evenement message envoyé
      --print("sent data")  
      end )
 
   conn:on("disconnection", function(conn)                 -- Evenement deconnexion
      print("disconnected:".. state .."Heap="..node.heap())  
-- plusieurs façon de terminer le traitement du mail 
-- fermer seulement la connexion, Reboot, ou se mettre en veille  (avec pin32 et pin8 reliées) avec un boot à la sortie de veille.
      conn:close()  conn=nil
      collectgarbage()  -- ramasse miettes pour faire le ménage dans la mémoire
      print("Finramasse miettes"   .. "Heap=" .. node.heap() )
      node.restart()  -- reboot 
      -- node.dsleep(5000000)  -- reveil dans n microseconds selement si   PIN32(RST) et PIN8(XPD_DCDC)  reliées
   end )

-- Fin réponses aux Evenements

-- on se connecte au serveur SMTP
-- la fonction sendmail va se terminer mais elle sera reveillée par les Evenements conn:on("xxxx" ...)
   print("connecting to " .. smtp_server .. ":" .. smtp_port)
   conn:connect(smtp_port,smtp_server)
end  -- fin fonction sendmail

-- connexion au WIFI en mode Station 
wifi.setmode(wifi.STATION)
wifi.sta.config("SSID","xxxxxxxx")
print(wifi.sta.getip())  -- Adresse IP allouée par le DHCP du routeur
print(wifi.sta.getmac())  -- Adresse MAC esp8266

-- Envoi d'un mail
-- sendmail("from@xxx.yyy","to@xxx.yyy","subject","body1\r\n body2 …","smtp.server.xxx:25")
sendmail("michel.esp8266@orange.fr","esp8266.michel@orange.fr","test envoi mail par esp8266   ","test   \r\n  à 15H17 ","smtp.orange.fr:25")
print("fin" ..node.heap())   -- attention le print s'execute avant la fin de l'envoi du mail
Donc un module esp8266 < 3€, deux piles AAA, et un capteur suffisent pour envoyer une alerte par mail.
On pourrait améliorer le principe en ajoutant un fichier log pour tracer les alertes.
C’est assez facile en lua car on a toutes les fonctions sur fichiers nécessaires :
open, close, readline, writeline, read, write, flush, seek, list, format, rename
Un appel à un serveur NTP pourrait permettre de dater les alertes.
Et pourquoi ne pas envoyer le fichier log en pièce jointe.

Cette puce esp8266, elle à tout d’une grande.

En principe les serveurs de mails sont toujours actifs.
si l'on veut perdre aucun mail, il faut mettre en file d'attente dans un fichier les mails en erreur d'émission (en testant les codes retour envoyés par le serveur SMTP). pour les envoyer plus tard.

On peut si l'on veut traiter les mails en provenance des esp8266 écrire un programme par exemple en python sur un Raspberry qui récupéré des mails structurés d'une certaine façon et qui les traite.

Prochaine étape, tester le protocole MQTT (machine to machine) prévu dans lua.
Ce protocole va peut être s’imposer dans l’Internet des objets (IOT : Internet Of Things).

Mais avant un exemple simple d'utilisation de python pour se connecter sur un esp8266 configuré en serveur Telnet

SMBA38.

Re: Tous les capteurs reliés au RPI par Wifi avec module ESP

Posté : jeu. 26 févr. 2015 10:58
par smba38
ESP8266 et python
pour récupérer les données d'un esp8266 , on peut faire plus simple, et Jean-Marie je pense que c'est ce que tu recherches,
On peut ne mettre aucune intelligence dans le programme lua à part la gestion d'un mini serveur Telnet.
ensuite on se connecte en python sur ce serveur et on envoie des lignes en langage lua pour par exemple lire un capteur.
Les données envoyées en retour sont lues et traitées par le programme python.
J'ai fait un essai dont voici la trace.

Code : Tout sélectionner

pi@raspberrypi:~/esp8266/telnet$ python client_telnet.py 192.168.1.10 2323
Connected to remote host
Welcome to NodeMcu world.
> print ("lecture capteur=" .. adc.read(0))
> lecture capteur=55
> print ("lecture capteur=" .. adc.read(0))
> lecture capteur=53
En fait cette méthode permet de prendre la main à distance sur l'interpréteur lua.

Voici le programme lua du serveur Telnet.

Code : Tout sélectionner

    -- a simple telnet server
wifi.setmode(wifi.STATION)
wifi.sta.config("SSID","clef wifi")
print(wifi.sta.getip())  -- Adresse IP allouée par le DHCP du routeur
print(wifi.sta.getmac())  -- Adresse MAC esp8266

    s=net.createServer(net.TCP,180) 
    s:listen(2323,function(c) 
       function s_output(str) 
          if(c~=nil) 
             then c:send(str) 
          end 
       end 
       node.output(s_output, 0)   -- re-direct output to function s_ouput.
       c:on("receive",function(c,l) 
          node.input(l)           -- works like pcall(loadstring(l)) but support multiple separate line
       end) 
       c:on("disconnection",function(c) 
          node.output(nil)        -- un-regist the redirect output function, output goes to serial
       end) 
       print("Welcome to NodeMcu world.")
    end)
Et le programme python voir http://www.binarytides.com/code-telnet- ... ts-python/

Code : Tout sélectionner

# telnet program example
import socket, select, string, sys
 
#main function
if __name__ == "__main__":
     
    if(len(sys.argv) < 3) :
        print 'Usage : python telnet.py hostname port'
        sys.exit()
     
    host = sys.argv[1]
    port = int(sys.argv[2])
     
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(2)
     
    # connect to remote host
    try :
        s.connect((host, port))
    except :
        print 'Unable to connect'
        sys.exit()
     
    print 'Connected to remote host'
     
    while 1:
        socket_list = [sys.stdin, s]
         
        # Get the list sockets which are readable
        read_sockets, write_sockets, error_sockets = select.select(socket_list , [], [])
         
        for sock in read_sockets:
            #incoming message from remote server
            if sock == s:
                data = sock.recv(4096)
                if not data :
                    print 'Connection closed'
                    sys.exit()
                else :
                    #print data
                    sys.stdout.write(data)
             
            #user entered a message
            else :
                msg = sys.stdin.readline()
                s.send(msg)
on lance le programme python par
python client_telnet.py 192.168.1.10 2323
le port utilisé est le 2323 ( par défaut pour Telnet c'est le port 23 qui est utilisé).

Les dernières lignes du programme sont à modifier en fonction des besoins:
On peut par exemple tester que le caratère ">" (le prompt) est bien envoyé en début de ligne

Code : Tout sélectionner

            #print data
                    sys.stdout.write(data)             
            #user entered a message
            else :
                msg = sys.stdin.readline()
                s.send(msg)
on peut également utiliser simplement le programme telnet (sur Windows ou sur Linux).
sur mon raspberry j'ai installé telnet -> sudo apt-get install telnet
puis lancé telnet sur le port 2323

Code : Tout sélectionner

pi@raspberrypi:~/esp8266/telnet$ telnet 192.168.1.10 2323
Trying 192.168.1.10...
Connected to 192.168.1.10.
Escape character is '^]'.
Welcome to NodeMcu world.
>  print ("lecture capteur=" .. adc.read(0))
lecture capteur=57
>
Il existe même des serveurs et des clients Telnet pour Arduino ?.

Voila, c'est tout pour aujourd'hui.

A+ Michel.

Re: Tous les capteurs reliés au RPI par Wifi avec module ESP

Posté : jeu. 26 févr. 2015 11:37
par Veloce
Jean-Marie a écrit :Dans ma lecture sur les sockets, je n'en suis qu'à la page 13 (sur 95). Je suis empêtré dans des structures incluses dans d'autres structures, faisant à nouveau partie de structures. Pour couronner tout cela, on peut faire par endroit du typecasting. Autant dire que pour un débutant en C, c'est pas du gâteau !!! Mais j'ignore si les choses seraient plus simples en Lua.
Je suis à l'écoute des avis.
Bah moi j'en suis à la page 23, mais sur 104 : tu parles bien du bouquin de Beej ? C'est un peu un millefeuille ces sockets, mais si on suit les exemples étape par étape ça se comprend à peu près. Ce que je n'ai pas pigé c'est ce qui se passe pendant qu'on attend la réponse du serveur en face: est-ce que le programme reste bloqué sur recv et attend indéfiniment, ou quoi. Enfin il me reste 81 pages à lire et je passe ma vie dans les transports en commun... :?
On peut facilement réaliser un serveur Web avec un module ESP8266.
J'utilise la carte de développement Nodemcu ( Un dizaine d'euros).
http://www.electrodragon.com/product/es ... ent-board/
Cette carte est à base de ESP-12 et elle dispose d'une entrée ADC.
Cette carte se programme en Lua, langage orienté réseau.
J'ai réalisé un serveur petit WEB qui permet de visualiser les valeurs d'un capteur MQ3 (éthylomètre).
Le programme utilise un cinquantaine de lignes de code (une grande partie du code est pour générer la page HTML).
Lua dispose de modules GPIO, PWM, I2C, ADC, SPI, Onewire.
J'aime bien ta carte SMBA38, et merci pour toutes ces infos. Je ne connaissais pas LUA et c'est vraiment intéressant.
Cela dit pour l'instant je reste sur mon idée de brancher un Arduino et d'utiliser les commandes AT: comme ça je peux utiliser
tous les exemples de programmes Arduino écrits dans un langage que je connais.

On a beaucoup parlé des sockets, mais c'est vrai, on peut aussi faire autrement. Si les modules ne font que de la collecte ou de l'alarme,
bref que ce sont eux qui ont l'initiative de la connexion, on peut les configurer non plus en serveurs mais en clients, qui postent un
formulaire sur un serveur web. Après, le serveur peut stocker les données dans une base pour faire des statistiques.
J'ai bien aimé ton exemple qui envoie des mails, merci ça ouvre plein de possibilités !

Euh, pardonne ma curiosité, mais tu veux brancher un... éthylomètre sur le web ? :shock:
Tu es gendarme ou c'est pour faire des concours de bière ?

Veloce

Re: Tous les capteurs reliés au RPI par Wifi avec module ESP

Posté : jeu. 26 févr. 2015 13:09
par smba38
Bonjour Veloce.

Pour l'éthylomètre, c'est la partie tests qui m'a amusé.
Pour étalonner le capteur (MQ-3), j'ai invité une dizaine de collègues retraités (un groupe de marcheurs) pour faire les tests.
A chaque verre j'ai pris des notes (au début).
Mais c'est compliqué car il faut tenir compte de la température, de l'hygrométrie, de la teneur en Oxygène ...
Bref un gadget de plus, mais on a bien rigolé.
le serveur WEB me servait à afficher en temps réel et sur grand écran les taux d'alcool en cours et maxi.

Je viens de poster un exemple de code python pour prendre la main à distance sur l'interpréteur lua d'un esp8266.
Je pense que ce code va plaire à Jean-Marie qui recherche la simplicité.
On peut créer des fichiers en langage lua pour faire des taches simples (un peu comme des macros).
Depuis le programme python on demande l'exécution de ces taches ou de simples commandes.

Code : Tout sélectionner

>print ("lecture capteur=" .. adc.read(0))
lecture capteur=57
> dofile("list.lua")
> name:mqtt7.lua, size:1236
name:telnet.lua, size:980
name:sendmail.lc, size:2312
name:list.lua, size:90
name:init.lua, size:850
En fonction des réponses de l'esp8266, on prend les décisions qui s'imposent.

Tu peux utiliser un Arduino, mais à la place de commandes AT tu envois via la liaison série des commandes en LUA.
C'est plus puissant car on peut avoir de l'intelligence sur l'Arduino et sur l'esp8266.
Et comme le langage LUA est orienté réseau on peut facilement faire des choses compliquées.

La puce de l'esp8266 est une puce avec un processeur 32 bits à 80MHZ.

Au passage quelques devises.
celle de l'informaticien : Pourquoi faire simple quand on peut faire compliqué (c'est un peu mon cas).
Celle du commercial: La réponse est oui, mais rappelez moi la question.
La mienne depuis que je suis retraité: Ne jamais remettre au lendemain ce que l'on peut faire le sur lendemain.

A +
SMBA38.