Mise en place d’un server web sur ESP8266 avec NodeMCU

J’en ai souvent parlé sur ce blog, et je pense que je n’ai pas fini de faire l’éloge du ESP8266. Ce petit module Wifi programmable est simplement génial. Nous allons voir dans cet article comment débuter avec un Module NodeMCU que vous pouvez trouver sur amazon pour largement moins de 10€. Attention, utiliser nodeMCU signifie programmer en Lua. Ca va changer un peu nos habitudes du C avec Arduino.


Cliquez ici pour acheter ce module sur amazon:

Installer le firmware NodeMCU

La première étape consiste à flasher le module avec le firmware NodeMCU, ici j’ai choisi d’utiliser le firmware 0.9. Notez que pour cette opération je suis sous MacOS. Les manipulations sont les mêmes sous Windows, mais l’environnement est à mon avais moins adapté au développement.

Télécharger le firmware ModeMCU

wget https://github.com/nodemcu/nodemcu-firmware/releases/download/0.9.6-dev_20150704/nodemcu_integer_0.9.6-dev_20150704.bin

Cloner le repository esptool qui est un programme python permettant de flasher le firmware téléchargé sur la carte.

git clone https://github.com/themadinventor/esptool.git

Avant de brancher le module lister les fichiers dans /dev/tty*, cela permettra de trouver le nouveau périphérique dans la liste

$>ls /dev/tty*     
/dev/tty			  /dev/ttyp6  /dev/ttypf  /dev/ttyq8  /dev/ttyr1  /dev/ttyra	/dev/ttys002  /dev/ttys011  /dev/ttys4	/dev/ttysd  /dev/ttyt6	/dev/ttytf  /dev/ttyu8	/dev/ttyv1  /dev/ttyva	/dev/ttyw3  /dev/ttywc
/dev/tty.Bluetooth-Incoming-Port  /dev/ttyp7  /dev/ttyq0  /dev/ttyq9  /dev/ttyr2  /dev/ttyrb	/dev/ttys003  /dev/ttys012  /dev/ttys5	/dev/ttyse  /dev/ttyt7	/dev/ttyu0  /dev/ttyu9	/dev/ttyv2  /dev/ttyvb	/dev/ttyw4  /dev/ttywd
/dev/tty.iPhone-WirelessiAP	  /dev/ttyp8  /dev/ttyq1  /dev/ttyqa  /dev/ttyr3  /dev/ttyrc	/dev/ttys004  /dev/ttys013  /dev/ttys6	/dev/ttysf  /dev/ttyt8	/dev/ttyu1  /dev/ttyua	/dev/ttyv3  /dev/ttyvc	/dev/ttyw5  /dev/ttywe
/dev/ttyp0			  /dev/ttyp9  /dev/ttyq2  /dev/ttyqb  /dev/ttyr4  /dev/ttyrd	/dev/ttys005  /dev/ttys014  /dev/ttys7	/dev/ttyt0  /dev/ttyt9	/dev/ttyu2  /dev/ttyub	/dev/ttyv4  /dev/ttyvd	/dev/ttyw6  /dev/ttywf
/dev/ttyp1			  /dev/ttypa  /dev/ttyq3  /dev/ttyqc  /dev/ttyr5  /dev/ttyre	/dev/ttys006  /dev/ttys015  /dev/ttys8	/dev/ttyt1  /dev/ttyta	/dev/ttyu3  /dev/ttyuc	/dev/ttyv5  /dev/ttyve	/dev/ttyw7
/dev/ttyp2			  /dev/ttypb  /dev/ttyq4  /dev/ttyqd  /dev/ttyr6  /dev/ttyrf	/dev/ttys007  /dev/ttys017  /dev/ttys9	/dev/ttyt2  /dev/ttytb	/dev/ttyu4  /dev/ttyud	/dev/ttyv6  /dev/ttyvf	/dev/ttyw8
/dev/ttyp3			  /dev/ttypc  /dev/ttyq5  /dev/ttyqe  /dev/ttyr7  /dev/ttys0	/dev/ttys008  /dev/ttys1    /dev/ttysa	/dev/ttyt3  /dev/ttytc	/dev/ttyu5  /dev/ttyue	/dev/ttyv7  /dev/ttyw0	/dev/ttyw9
/dev/ttyp4			  /dev/ttypd  /dev/ttyq6  /dev/ttyqf  /dev/ttyr8  /dev/ttys000	/dev/ttys009  /dev/ttys2    /dev/ttysb	/dev/ttyt4  /dev/ttytd	/dev/ttyu6  /dev/ttyuf	/dev/ttyv8  /dev/ttyw1	/dev/ttywa
/dev/ttyp5			  /dev/ttype  /dev/ttyq7  /dev/ttyr0  /dev/ttyr9  /dev/ttys001	/dev/ttys010  /dev/ttys3    /dev/ttysc	/dev/ttyt5  /dev/ttyte	/dev/ttyu7  /dev/ttyv0	/dev/ttyv9  /dev/ttyw2	/dev/ttywb

Repérer le nouveau périphérique USB. Pour moi c’est /dev/tty.wchusbserial1420. 

NB: Si le périphérique n’est pas reconnu par votre système, suivez ce tutorial pour installer les driver sous MacOS: http://www.homautomation.org/2015/02/05/how-to-use-arduinos-with-ch340g-ch341g-serialusb-ftdi-chip/

$>ls /dev/tty* 
/dev/tty			  /dev/ttyp5  /dev/ttype  /dev/ttyq7  /dev/ttyr0  /dev/ttyr9	/dev/ttys001  /dev/ttys010  /dev/ttys3	/dev/ttysc  /dev/ttyt5	/dev/ttyte  /dev/ttyu7	/dev/ttyv0  /dev/ttyv9	/dev/ttyw2  /dev/ttywb
/dev/tty.Bluetooth-Incoming-Port  /dev/ttyp6  /dev/ttypf  /dev/ttyq8  /dev/ttyr1  /dev/ttyra	/dev/ttys002  /dev/ttys011  /dev/ttys4	/dev/ttysd  /dev/ttyt6	/dev/ttytf  /dev/ttyu8	/dev/ttyv1  /dev/ttyva	/dev/ttyw3  /dev/ttywc
/dev/tty.iPhone-WirelessiAP	  /dev/ttyp7  /dev/ttyq0  /dev/ttyq9  /dev/ttyr2  /dev/ttyrb	/dev/ttys003  /dev/ttys012  /dev/ttys5	/dev/ttyse  /dev/ttyt7	/dev/ttyu0  /dev/ttyu9	/dev/ttyv2  /dev/ttyvb	/dev/ttyw4  /dev/ttywd
/dev/tty.wchusbserial1420	  /dev/ttyp8  /dev/ttyq1  /dev/ttyqa  /dev/ttyr3  /dev/ttyrc	/dev/ttys004  /dev/ttys013  /dev/ttys6	/dev/ttysf  /dev/ttyt8	/dev/ttyu1  /dev/ttyua	/dev/ttyv3  /dev/ttyvc	/dev/ttyw5  /dev/ttywe
/dev/ttyp0			  /dev/ttyp9  /dev/ttyq2  /dev/ttyqb  /dev/ttyr4  /dev/ttyrd	/dev/ttys005  /dev/ttys014  /dev/ttys7	/dev/ttyt0  /dev/ttyt9	/dev/ttyu2  /dev/ttyub	/dev/ttyv4  /dev/ttyvd	/dev/ttyw6  /dev/ttywf
/dev/ttyp1			  /dev/ttypa  /dev/ttyq3  /dev/ttyqc  /dev/ttyr5  /dev/ttyre	/dev/ttys006  /dev/ttys015  /dev/ttys8	/dev/ttyt1  /dev/ttyta	/dev/ttyu3  /dev/ttyuc	/dev/ttyv5  /dev/ttyve	/dev/ttyw7
/dev/ttyp2			  /dev/ttypb  /dev/ttyq4  /dev/ttyqd  /dev/ttyr6  /dev/ttyrf	/dev/ttys007  /dev/ttys017  /dev/ttys9	/dev/ttyt2  /dev/ttytb	/dev/ttyu4  /dev/ttyud	/dev/ttyv6  /dev/ttyvf	/dev/ttyw8
/dev/ttyp3			  /dev/ttypc  /dev/ttyq5  /dev/ttyqe  /dev/ttyr7  /dev/ttys0	/dev/ttys008  /dev/ttys1    /dev/ttysa	/dev/ttyt3  /dev/ttytc	/dev/ttyu5  /dev/ttyue	/dev/ttyv7  /dev/ttyw0	/dev/ttyw9
/dev/ttyp4			  /dev/ttypd  /dev/ttyq6  /dev/ttyqf  /dev/ttyr8  /dev/ttys000	/dev/ttys009  /dev/ttys2    /dev/ttysb	/dev/ttyt4  /dev/ttytd	/dev/ttyu6  /dev/ttyuf	/dev/ttyv8  /dev/ttyw1	/dev/ttywa

Flasher le firmware avec esptool:

$> cd esptool
$> sudo python ./esptool.py --port /dev/tty.wchusbserial1420 write_flash 0x00000 ../nodemcu_integer_0.9.6-dev_20150704.bin                                                                                    
esptool.py v1.2-dev
Connecting...
Auto-detected Flash size: 32m
Running Cesanta flasher stub...
Flash params set to 0x0040
Writing 450560 @ 0x0... 450560 (100 %)
Wrote 450560 bytes at 0x0 in 39.1 seconds (92.2 kbit/s)...
Leaving...

Nous y voilà le module est prêt.

Acceder au firmaware via la console.

Une fois le firmware bien installé, il s’agit de le tester, NodeMCU délivre un accès au système via le port Série USB. Il faut donc un terminal pour communiquer avec le module. De mon côté, j’utilise le terminal de l’environnement Arduino qui sera bien suffisant pour cette tâche. (NodeMCU communique à la vitesse de 9600 baud).

J’exécute donc le test le plus simple:

>print("Test")

capture-decran-2016-10-15-a-13-57-50

A ce stade tout fonctionne parfaitement, il faut maintenant mettre en place du code:

Mise en place d’un serveur Http

Le langage utilisé pour programmer les NodeMCU est le Lua. Pour plus d’information sur le langage je vous propose ce PDF: Lua http://thomaslauer.com/download/luarefv51.pdf

Voici donc le code que je veux charger sur mon module.

NB: il faut penser à changer ROUTER_ESSID et WIFI_PASSWORD par vos identifiants wifi.

wifi.setmode(wifi.STATION)
wifi.sta.config("ROUTER_ESSID","WIFI_PASSWORD")
print(wifi.sta.getip())
led1 = 3
led2 = 4
gpio.mode(led1, gpio.OUTPUT)
gpio.mode(led2, gpio.OUTPUT)
srv=net.createServer(net.TCP)
srv:listen(80,function(conn)
    conn:on("receive", function(client,request)
        local buf = "";
        local _, _, method, path, vars = string.find(request, "([A-Z]+) (.+)?(.+) HTTP");
        if(method == nil)then
            _, _, method, path = string.find(request, "([A-Z]+) (.+) HTTP");
        end
        local _GET = {}
        if (vars ~= nil)then
            for k, v in string.gmatch(vars, "(%w+)=(%w+)&*") do
                _GET[k] = v
            end
        end
        buf = buf.."<h1> ESP8266 Web Server</h1>";
        buf = buf.."<p>GPIO0 <a href=\"?pin=ON1\"><button>ON</button></a> <a href=\"?pin=OFF1\"><button>OFF</button></a></p>";
        buf = buf.."<p>GPIO2 <a href=\"?pin=ON2\"><button>ON</button></a> <a href=\"?pin=OFF2\"><button>OFF</button></a></p>";
        local _on,_off = "",""
        if(_GET.pin == "ON1")then
            gpio.write(led1, gpio.HIGH);
        elseif(_GET.pin == "OFF1")then
            gpio.write(led1, gpio.LOW);
        elseif(_GET.pin == "ON2")then
            gpio.write(led2, gpio.HIGH);
        elseif(_GET.pin == "OFF2")then
            gpio.write(led2, gpio.LOW);
        end
        client:send(buf);
        client:close();
        collectgarbage();
    end)
end)

Il est possible évidemment de copier ligne par ligne ce code dans la console pour le faire fonctionner mais ce n’est pas l’idéal. Il existe un autre utilitaire permettant de charger du code dans sur le ModeMCU:

$> git clone https://github.com/4refr0nt/luatool.git

J’ai pour ma part sauvegarder le code précédent dans le fichier suivant: ~/Dev/lua/simpleserver/init.lua, je vais donc le télécharger sur le ModeMCU. Mais avant ça, je conseille de faire un reset du ModeMCU pour éviter tout problème de port déjà ouvert ou autre.

$> python luatool/luatool/luatool.py --port /dev/tty.wchusbserial1420 --src ~/Dev/lua/simpleserver/init.lua --dest init.lua --restart     

->file.open("init.lua", "w") -> ok
->file.close() -> ok
->file.remove("init.lua") -> ok
->file.open("init.lua", "w+") -> ok
->file.writeline([==[wifi.setmode(wifi.STATION)]==]) -> ok
->file.writeline([==[wifi.sta.config("ROUTER_ESSID","WIFI_PASSWORD")]==]) -> ok
->file.writeline([==[print(wifi.sta.getip())]==]) -> ok
->file.writeline([==[led1 = 3]==]) -> ok
->file.writeline([==[led2 = 4]==]) -> ok
->file.writeline([==[gpio.mode(led1, gpio.OUTPUT)]==]) -> ok
->file.writeline([==[gpio.mode(led2, gpio.OUTPUT)]==]) -> ok
->file.writeline([==[srv=net.createServer(net.TCP)]==]) -> ok
->file.writeline([==[srv:listen(80,function(conn)]==]) -> ok
->file.writeline([==[conn:on("receive", function(client,request)]==]) -> ok
->file.writeline([==[local buf = "";]==]) -> ok
->file.writeline([==[local _, _, method, path, vars = string.find(request, "([A-Z]+) (.+)?(.+) HTTP");]==]) -> ok
->file.writeline([==[if(method == nil)then]==]) -> ok
->file.writeline([==[_, _, method, path = string.find(request, "([A-Z]+) (.+) HTTP");]==]) -> ok
->file.writeline([==[end]==]) -> ok
->file.writeline([==[local _GET = {}]==]) -> ok
->file.writeline([==[if (vars ~= nil)then]==]) -> ok
->file.writeline([==[for k, v in string.gmatch(vars, "(%w+)=(%w+)&*") do]==]) -> ok
->file.writeline([==[_GET[k] = v]==]) -> ok
->file.writeline([==[end]==]) -> ok
->file.writeline([==[end]==]) -> ok
->file.writeline([==[buf = buf.."<h1> ESP8266 Web Server</h1>";]==])
->file.writeline([==[buf = buf.."<p>GPIO0 <a href=\"?pin=ON1\"><button>ON</button></a> <a href=\"?pin=OFF1\"><button>OFF</button></a></p>";]==])
->file.writeline([==[buf = buf.."<p>GPIO2 <a href=\"?pin=ON2\"><button>ON</button></a> <a href=\"?pin=OFF2\"><button>OFF</button></a></p>";]==])
->file.writeline([==[local _on,_off = "",""]==])
->file.writeline([==[if(_GET.pin == "ON1")then]==]) -> ok
->file.writeline([==[gpio.write(led1, gpio.HIGH);]==]) -> ok
->file.writeline([==[elseif(_GET.pin == "OFF1")then]==]) -> ok
->file.writeline([==[gpio.write(led1, gpio.LOW);]==]) -> ok
->file.writeline([==[elseif(_GET.pin == "ON2")then]==]) -> ok
->file.writeline([==[gpio.write(led2, gpio.HIGH);]==]) -> ok
->file.writeline([==[elseif(_GET.pin == "OFF2")then]==]) -> ok
->file.writeline([==[gpio.write(led2, gpio.LOW);]==]) -> ok
->file.writeline([==[end]==]) -> ok
->file.writeline([==[client:send(buf);]==]) -> ok
->file.writeline([==[client:close();]==]) -> ok
->file.writeline([==[collectgarbage();]==]) -> ok
->file.writeline([==[end)]==]) -> ok
->file.writeline([==[end)]==]) -> ok
->file.flush() -> ok
->file.close() -> ok
->node.restart() -> ok
--->>> All done <<<---

Test de l’application

Voilà tout est prêt. Pour tester cela il nous faut connaitre l’IP du NodeMCU. Pour cela se connecter à nouveau via le serial et taper:

> print(wifi.sta.getip())
192.168.0.21  255.255.255.0  192.168.0.1

capture-decran-2016-10-15-a-14-17-33
Il ne reste maintenant à se connecter sur cette ip pour tester.
capture-decran-2016-10-15-a-14-23-41

Connecter une led sur le GPIO0

Pour finir de bien valider que tout fonctionne, on va ajouter une LED sur le GPIO0. Il nous faut pour cela le « pinout » de NodeMCU:
nodemcu__v1-0_pinout
Nous pouvons donc utiliser le montage suivant:
NB: vous pouvez télécharger le composant NodeMCU pour Fritzing ici
nodemculed

 

Le résultat en image:

Source: http://www.cnx-software.com/2015/10/29/getting-started-with-nodemcu-board-powered-by-esp8266-wisoc/

2 thoughts on “Mise en place d’un server web sur ESP8266 avec NodeMCU

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *