Sie sind auf Seite 1von 51

Programming

ESP8266-based
Wireless Systems
in MicroPython



By Yury Magda


Copyright © 2017 by Yury Magda. All rights reserved.

The programs, examples, and applications presented in this book
have been included for their instructional value. The author offers no
warranty implied or express, including but not limited to implied
warranties of fitness or merchantability for any particular purpose
and do not accept any liability for any loss or damage arising from
the use of any information in this book, or any error or omission in
such information, or any incorrect use of these programs, procedures,
and applications.
No part of this publication may be reproduced, stored in a retrieval
system, or transmitted in any form or by any means, electronic,
mechanical, photocopying, recording, or otherwise, without the prior
written permission of the author.

Contents
Introduction
Disclaimer
Configuring ESP8266
Running commands via a serial interface
Handling the file system on the ESP8266 board
Using WebREPL
Programming wireless network systems with ESP8266
Driving digital outputs: project 1
Driving digital outputs: project 2
Programming PWM
Reading analog signals: project 1
Reading analog signals: project 2
Reading analog signals using a Web Server
Reading digital inputs: project 1
Reading digital inputs: project 2
Reading digital inputs using a Web Server
Introduction

This book describes the basic principles of programming wireless Wi-Fi applications based on
ESP8266-compatible boards using a MicroPython programming language. MicroPython is a lean
and efficient implementation of the Python 3 and includes a small subset of the Python standard
library. MicroPython is optimized to run on most popular microcontrollers (ATSAMD21,
STM32, ESP8266, etc.) and in constrained environments.

MicroPython is packed full of advanced features such as an interactive prompt, arbitrary
precision integers, closures, list comprehension, generators, exception handling and more. Yet it
is compact enough to fit and run within just 256k of code space and 16k of RAM. MicroPython
aims to be as compatible with normal Python as possible to allow you to transfer code with ease
from the desktop to a microcontroller or embedded system.

The book contains various projects of simple wireless measurement and control systems. Each
project is accompanied by a brief description which helps to make things clear. All projects
described in this guide can be easily improved or modified if necessary.

All wireless applications were build and tested on the desktop PC running Linux (Ubuntu 16.04)
and a NodeMCU 1.0 (ESP-12E) board equipped with ESP8266 CPU. The source code of
applications was developed in Python 3 and MicroPython.
Disclaimer

The design techniques described in this book have been tested on the NodeMCU 1.0 (ESP-12E)
without damage of the equipment. I will not accept any responsibility for damages of any kind due
to actions taken by you after reading this book.

Configuring ESP8266

Before using an ESP8266 we should configure its firmware. After the ESP8266 module has been
connected to a USB port of the PC, a serial interface is assigned to the board. We can easily
check this by entering the following command in the Terminal window:

$ ls -l /dev/ttyU*
crw-rw---- 1 root dialout 188, 0 гру 25 10:43 /dev/ttyUSB0

In this particular case, our ESP8266 board (NodeMCU) is associated with a /dev/ttyUSB0
device. This device will be used when configuring our board to operate in the MicroPython
environment.

First, erase the flash memory of ESP8266 board using the esptool.py utility that should
previously be installed in Linux. The following command erases the flash, producing the output
shown below:

$ esptool.py --port /dev/ttyUSB0 erase_flash
esptool.py v1.3-dev
Connecting...
Couldn't connect. [<class '__main__.FatalError'>; Timed out waiting for packet header].
Retrying...
Running Cesanta flasher stub...
Erasing flash (this may take a while)...
Erase took 8.5 seconds

After erasing is complete, we can write the MicroPython interpreter in a flash memory of
ESP8266. To do that, we should download the latest stable MicroPython image for ESP8266
from http://microbit.org/download. The firmware for ESP8266 can be found in the section
“Firmware for ESP8266 boards”. In my case, this was the file esp8266-20161110-v1.8.6.bin.

Then deploy the new firmware using the esptool.py command as is show below:

$ esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=detect 0 esp8266-
20161110-v1.8.6.bin

In my case, the command produced the following output:

$ esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=detect 0 esp8266-
20161110-v1.8.6.bin
esptool.py v1.3-dev
Connecting...
Couldn't connect. [<class '__main__.FatalError'>; Timed out waiting for packet header].
Retrying...
Auto-detected Flash size: 32m
Running Cesanta flasher stub...
Flash params set to 0x0040
Wrote 569344 bytes at 0x0 in 12.6 seconds (362.3 kbit/s)...
Leaving...

After the above steps succeeded, we can access the MicroPython environment on the NodeMCU
board using a REPL command prompt.


Running commands via a serial interface

The easiest way to test out a code and run commands is to use the REPL (Read Evaluate Print
Loop). REPL is the interactive MicroPython prompt used to interact with a ESP8266 board. To
access the REPL we can use either an UART serial interface or Wi-Fi.
The REPL is always available on the UART0 serial interface which uses pins GPIO1 (TX) and
GPIO3 (RX). The baud rate of the REPL is 115200. If a ESP8266 board has a USB-to-UART
interface as in the case of NodeMCU, then we will be able to access the REPL directly from the
PC. Otherwise, you will need to have a way of communicating with the UART.
To access the prompt over USB-serial we need to use some terminal emulator program. In
Windows, TeraTerm is a good choice, on Mac we can use the built-in screen program, and Linux
we can use picocom, minicom or screen. In this guide, will use the screen utility.

In Ubuntu 16.04, screen is launched by entering:
$ screen /dev/ttyUSB0 115200

Once the connection over the serial port is established, we can test it by pressing Enter a few
times until the MicroPython REPL prompt (>>>) appears.
The following example illustrates how to execute a simple script that toggles the on-board LED
on pin GPIO16 of the NodeMCU board.

>>> import machine
>>> import time
>>> cnt = 0
>>> led = machine.Pin(16, machine.Pin.OUT)
>>> while cnt < 10:
... led.high()
... time.sleep(0.5)
... led.low()
... time.sleep(0.5)
... cnt += 1
... led.high()
>>>

We can execute even more complicated scripts from the REPL prompt, but it would be much
better to have the capability to create, edit, save and run MicroPython scripts directly on the
ESP8266 board. To do that, we need to use any of a few utilities described in the following
section.

Handling the file system on the ESP8266 board

In order to manipulate files located on the ESP8266 board, we should know how the MicroPython
controls a file system.
Typing a code within the serial REPL would be suitable when we need to run small scripts.
Developing and running complex programs may require other tools. MicroPython has an internal
file system which can store code that runs whenever the board powers up.
In this guide, we'll use the Adafruit MicroPython tool (ampy) to load files and run a MicroPython
code on a ESP8266 board.
Note that all ESP8266-compatible boards reserve just a small part of their internal flash memory
for the file system.

The ampy utility can be downloaded from https://github.com/adafruit/ampy. ampy is not the only
tool for manipulating files and more on a MicroPython board, there are several other tools
described on the Adafruit site www.adafruit.com. They are listed below:

ESP8266 WebREPL - For ESP8266-based boards the WebREPL provides a basic
web interface for uploading files to the board. This is handy for dropping a file on a
board, but it requires being connected to the WebREPL which might not always be
convenient.
rshell - a remote MicroPython shell tool which allows you to access the files and more
from a MicroPython board connected over its serial/USB connection.
mpfshell - similar to rshell and provides file and REPL access in a MicroPython-specific
shell. However, mpfshell is made specifically to support ESP8266-based boards and the
WiPy board.

This guide uses ampy because it is a simple cross-platform command line tool that provides just
enough functionality to access a MicroPython's file system without being too complex. Be aware
that ampy does not support talking to a boards without a serial/USB REPL connection.

Note that before using a tool like ampy for ESP8266-based boards, we might need to disable
debug
output on the board. If you're using an official release build of MicroPython (i.e. one that ends in a
simple version like 1.8.6 instead of a more complex daily build like 1.8.6-xx-xxxxxxxx) debug
output is already disabled and you don't need to do anything extra. However, if you're using a
daily build or custom build from source you'll need to disable debug output that can confuse tools
like ampy.
To disable debug output on ESP8266, we should establish the connection to the ESP8266 via a
serial REPL and run the following commands:

import esp
esp.osdebug(None)

The esp.osdebug() function returns no output. After running the command debug output will not be
printed to the serial terminal and we can use tools like ampy.
It is highly recommended to add the above two lines to the board's boot.py file so debug output is
disabled permanently. If you don't make this change, you'll need to manually disable debug output
every time you reset the board!

With ampy we can take a MicroPython code written on the PC and run it on a connected
MicroPython board. This gives us a simple workflow for exploring MicroPython. We can write a
code on the PC in some text editor, then invoke ampy with the run command to run the code on a
board!
To use the run command, we should just specify a path to a Python file on the PC. The ampy
program will
send the file to the board, wait for it to finish running, and print any output from the program.
For example, let’s put the following MicroPython code

print('Hello world! I can count to 10:')
for i in range(1,11):
print(i)

in the file test.py on the PC. To execute the code inside this file on the connected ESP8266
board, we should open the terminal window in the directory where test.py resides and enter the
command:

$ ampy --port /serial/port run test.py

where /serial/port is the path or name of the serial port connected to the MicroPython board. In
our case, this will be /dev/ttyUSB0.

If you don't want to constantly specify the --port option, you can set the AMPY_PORT
environment variable in your terminal session. The ampy utility will use this variable for
connecting to the board's serial port.
Be aware that the run command is not a shell or tool that allows you to send input from your
computer to the board! If you need to send input, you'll want to connect to the board and use its
serial REPL.

By default, the run command will wait for the script to finish running on the board before printing
its output. In some cases, you don't want this behavior, for example, if your script has a main or
infinite loop that never returns.
In this case, add the --no-output option to the run command. This flag tells ampy not to wait for
any output and instead just start running the script and return. The following example illustrates
this approach:

import time
print('Counting...')
i = 1
while True:
print(i)
i += 1
time.sleep(1.0) # Delay for 1 second.

Save the above MicroPython code in the test.py file and run the application with the --no-output
option as is shown below:

$ ampy --port /serial/port run --no-output test.py

The ampy utility can also be used for uploading files to the ESP8266:

$ ampy --port /dev/ttyUSB0 put blinky.py

When we need to replace a file that already exists on ESP8266 (for example, main.py) with some
file (for example, main1.py), we can use the following command:

$ ampy --port /dev/ttyUSB0 put main1.py /main.py

To view the files on the ESP8266 we can use the ls command:

$ ampy --port /dev/ttyUSB0 ls

We can also download file contents from the board into some file on the PC. The following
command writes the content of the file main.py on the ESP8266 into the file main1.py that will be
created in the current directory:

$ ampy --port /dev/ttyUSB0 get main.py > main1.py

The rm command allows to remove a specified file from the board:

$ ampy --port /dev/ttyUSB0 rm test.py

The list of options supported by the ampy utility can be obtained using the help option:

$ ampy --help
Usage: ampy [OPTIONS] COMMAND [ARGS]...

ampy - Adafruit MicroPython Tool

ampy is a tool to control MicroPython boards over a serial connection.
Using ampy you can manipulate files on the board's internal filesystem
and even run scripts.

Options:
-p, --port PORT Name of serial port for connected board. Can
optionally specify with AMPY_PORT environment
variable. [required]
-b, --baud BAUD Baud rate for the serial connection (default 115200).
Can optionally specify with AMPY_BAUD environment
variable.
--version Show the version and exit.
--help Show this message and exit.

Commands:
get Retrieve a file from the board.
ls List contents of a directory on the board.
mkdir Create a directory on the board.
put Put a file on the board.
reset Perform soft reset/reboot of the board.
rm Remove a file from the board.
run Run a script and print its output.


Using WebREPL

WebREPL allows you to use the Python prompt over Wi-Fi for establishing the connection to the
ESP8266 board through a Web browser (the latest versions of Firefox and Chrome are
supported).
For your convenience, WebREPL client is hosted at http://micropython.org/webrepl .
Alternatively, you can install it locally from the GitHub
repository https://github.com/micropython/webrepl .

Before connecting to WebREPL, you should set a password and enable the interface via a normal
serial connection. Initial versions of MicroPython for ESP8266 came with WebREPL
automatically enabled on the boot and with the ability to set a password via Wi-Fi on the first
connection, but as WebREPL was becoming more widely known and popular, the initial setup has
switched to a wired connection for improved security.

After we have connected to the ESP8266 board via a serial interface, enter the command:

>>> import webrepl_setup

Then we should follow the on-screen instructions and prompts. For example, in Ubuntu 16.04 we
can see the following sequence:

>>> import webrepl_setup
WebREPL daemon auto-start status: disabled

Would you like to (E)nable or (D)isable it running on boot?
(Empty line to quit)
> E
To enable WebREPL, you must set password for it
New password: 1234
Confirm password: 1234
Changes will be activated after reboot
Would you like to reboot now? (y/n)

After pressing “y” the board will be reset. We will get something similar to:

>>>
WebREPL daemon started on ws://192.168.4.1:8266
Started webrepl in normal mode
could not open file 'main.py' for reading

MicroPython v1.8.6-7-gefd0927 on 2016-11-10; ESP module with ESP8266
Type "help()" for more information.
>>>

To check the network interfaces, we can execute the following sequence typed in REPL:

>>> import network
>>> sta_if = network.WLAN(network.STA_IF)
>>> ap_if = network.WLAN(network.AP_IF)
>>> sta_if.active()
False
>>> ap_if.active()
True
>>> ap_if.ifconfig()
('192.168.4.1', '255.255.255.0', '192.168.4.1', '208.67.222.222')
>>> sta_if.ifconfig()
('0.0.0.0', '0.0.0.0', '0.0.0.0', '208.67.222.222')
>>>

It is seen that the ESP8266 board is configured as an Access Point (AP) with an IP-address
192.168.4.1 (by default). Most configurations (including my own) uses a standalone Wi-Fi router
configured AP, while other nodes are configured as stations. For that reason, I reconfigured
ESP8266 for operating as a station.

In such configuration, the ESP8266 receives the IP-address from the DHCP server running on a
WI-Fi router (TP-LINK, in my case). The following sequence typed in REPL was used to
configure ESP8266 as a Wi-Fi station:

>>> sta_if.active(True)
#5 ets_task(4020ed88, 28, 3fff9708, 10)
>>> sta_if.connect('TP-LINK_77D8', 'password') # connect to the Wi-Fi network using a TP-
LINK router
>>> sta_if.isconnected()
True
>>> sta_if.ifconfig()
('192.168.0.107', '255.255.255.0', '192.168.0.1', '192.168.0.1')
>>>

The last command, sta_if.ifconfig(), gives you the information about the network where a
ESP8266 board is connected to.
In my configuration, the IP-address of the ESP8266 station (192.168.0.107) is taken from a
reserved pool of IP-addresses determined for the DHCP server. Using a predetermined IP-
address simplifies development of wireless applications, since your program doesn’t need to
scan a network.

We can easily test if a network interface on ESP8266 is activated by executing a standard Linux
utility called ping. The ping command checks if the destination network node can be reached by
sending the ICMP packets. In our case, after configuring ESP8266 we can test its network
interface as follows:
$ ping 192.168.0.107
PING 192.168.0.101 (192.168.0.107) 56(84) bytes of data.
64 bytes from 192.168.0.107: icmp_seq=1 ttl=255 time=101 ms
64 bytes from 192.168.0.107: icmp_seq=2 ttl=255 time=20.0 ms
64 bytes from 192.168.0.107: icmp_seq=3 ttl=255 time=42.8 ms
64 bytes from 192.168.0.107: icmp_seq=4 ttl=255 time=67.8 ms
64 bytes from 192.168.0.107: icmp_seq=5 ttl=255 time=87.9 ms
64 bytes from 192.168.0.107: icmp_seq=6 ttl=255 time=7.04 ms
64 bytes from 192.168.0.107: icmp_seq=7 ttl=255 time=3.40 ms
64 bytes from 192.168.0.107: icmp_seq=8 ttl=255 time=3.40 ms
64 bytes from 192.168.0.107: icmp_seq=9 ttl=255 time=1.81 ms

Two configurations (an AP and station) described above can be used for launching WebREPL. To
test WebREPL, we should launch type the following URL in a Web browser:

http://micropython.org/webrepl/

After WebREPL has been launched (Fig.1), we should enter the IP-address of ESP8266
(192.168.0.107, in our case) leaving the port (8266) unchanged. When done, press “Connect”.


Fig.1
If the connection succeeds, we should see a password prompt (Fig.2).

Fig.2
Once we have typed the password, press Enter once more to get a prompt “>>>” (Fig.3).

Fig.3
You can now start typing MicroPython commands as is shown in the above figure. To disconnect
from WebREPL, you can press the “Disconnect” button (Fig.4).


Fig.4
To automatically establish the connection to our Wi-Fi network, we can use the following function
(Listing 1):

Listing 1.

def do_connect():
import network
sta_if = network.WLAN(network.STA_IF)
if not sta_if.isconnected():
print('connecting to network...')
sta_if.active(True)
sta_if.connect('<essid>', '<password>')
while not sta_if.isconnected():
pass
print('network config:', sta_if.ifconfig())

The above source code should be written in the boot.py file on the ESP8266 board.
The practical example of the source code for connecting to my home Wi-Fi network is shown in
Listing 2. This code is put in the main.py file that is executed after boot.py terminates.

Listing 2.

import network
sta_if = network.WLAN(network.STA_IF)
ap_if = network.WLAN(network.AP_IF)
ap_if.active(False)
if not sta_if.isconnected():
sta_if.active(True)
sta_if.connect('TP-LINK_77D8', 'password') # connect to my home Wi-Fi network

In my particular case, an ESP8266 station will be assigned the IP-address 192.168.0.107 on a
network 192.168.0.0.
The following sections describe the basic concepts of building various wireless network systems
for measurement and control using the ESP8266 board (NodeMCU).

Programming wireless network systems with ESP8266

There may be a lot of methods to configure and program network Wi-Fi measurement systems.
Generally, wireless network applications use the “client-server” configuration that is widely used
in wired networks.
When running, the network application may function as a "server" or as a "client". Often a
network application is developed for operating in both modes, depending on some predetermined
conditions. The block diagram in Fig.5 illustrates the basic “client–server" configuration.



Fig.5



Here you can see an interaction between three network applications (a TCP server and two TCP
clients). The TCP server is assigned the IP address 192.168.0.100 and port 8089 – these network
parameters are used for waiting for incoming requests from TCP clients.

Let’s assume that the TCP Client 1 running on some network node tries to connect to the
TCP Server running on another node. Initially, the TCP Client 1 puts a request to the TCP Server
using the basic network parameters (192.168.0.100: 8089). The TCP Server discovers this
request and creates a working connection (“working socket”) to the TCP Client 1. Besides, the
TCP Server specifies the parameters of the working connection (IP address = 192.168.0.100 and
port = 47901) and passes them to the TCP Client 1.
Data transfer between the TCP server and TCP Client 1 will be performed using this working
socket which have to be closed after operations have completed.

Again, when the TCP Client 2 establishes connection to the TCP Server, the new working
connection with an IP address 192.168.0.100 and port 48344 is created. Note, that the "listening
socket" using port 8089 of the TCP Server serves only for establishing communication between
the TCP Server and TCP clients. This socket only listens for incoming requests from TCP clients
and forces the TCP Server to create a new working connection if needed. When the TCP Server
terminates it has to close the "listening" socket. Once a communication channel has been created,
data can be transferred in both directions between a TCP Server and TCP Client this mainly
depends on a control algorithm.

When designing the simplest Wi-Fi network system, we need at least one TCP Server and one
TCP Client. In this case, a Wi-Fi board can be either “TCP Server” or “TCP Client”. In more
complicated configurations, the program code running on the Wi-Fi board can run both TCP
Server and TCP client.
In this guide, we will consider the simplest configurations where Wi-Fi boards will run only a
TCP server or TCP Client at a time.
The following sections describe practical designs of simple wireless measurement and control
systems.

Driving digital outputs: project 1

This project illustrates designing a simple wireless control system that will drive GPIO5 and
GPIO16 pins of NodeMCU ON/OFF from the PC. In this system, the TCP server application is
running on the remote ESP8266 board, while a TCP client is running on the PC.
The GPIO16 pin drives the on-board LED that is connected to +3.3V via a pull-up resistor. The
GPIO5 pin drives the LED connected to ESP8266 through resistor R1 as is shown in Fig.6.


Fig.6

The MicroPython source code of the TCP server is shown in Listing 3.

Listing 3.

import machine
import time
import network
import socket

sta_if = network.WLAN(network.STA_IF)
ap_if = network.WLAN(network.AP_IF)
ap_if.active(False)
if not sta_if.isconnected():
sta_if.active(True)
sta_if.connect('TP-LINK_77D8', 'password') # connect to my Wi-Fi network

time.sleep(2)

# create a socket object
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

host = '192.168.0.107'
port = 55000

# bind to the port
serverSocket.bind((host, port))

# queue up to 5 requests
serverSocket.listen(5)

while True:
# establish a connection
clientSocket, addr = serverSocket.accept()
sRecv = clientSocket.recv(128)
sASCII = sRecv.decode('utf8')
sParam = sASCII.split(' ')
if sParam[0] == 'GPOUT':
pin = int(sParam[1])
val = int(sParam[2])
led = machine.Pin(pin, machine.Pin.OUT)
led.value(val)
clientSocket.send(sRecv)
clientSocket.close()

In this source code, the sequence

sta_if = network.WLAN(network.STA_IF)
ap_if = network.WLAN(network.AP_IF)
ap_if.active(False)
if not sta_if.isconnected():
sta_if.active(True)
sta_if.connect('TP-LINK_77D8', 'password')

puts the NodeMCU into “station” mode and establishes the connection to the Wi-Fi network. Once
the board is connected to Wi-Fi, the network interface of NodeMCU is assigned the IP address
192.168.0.107. This address will be used for configuring the TCP Server.
The sequence

serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = '192.168.0.107'
port = 55000
serverSocket.bind((host, port))
serverSocket.listen(5)

creates the server socket object serverSocket associated with the IP-address 192.1168.0.107
and port 55000. The TCP server will wait for incoming requests (max = 5) on this socket.
The client requests are processed in the endless while loop. After the client connection is
accepted, the new “working” socket is created by the command:

clientSocket, addr = serverSocket.accept()


All operations with the client will then be performed using the clientSocket socket. In our case,
the clientSocket receives the command string from the TCP client and saves the data in the string
variable aASCII:

sRecv = clientSocket.recv(128)
sASCII = sRecv.decode('utf8')

The following sequence parses the sASCII string, determines the pin to drive (the pin variable),
then determines the value to write to this pin (the val variable). The pin to drive is kept in the led
variable. Finally, the value val will be written to the pin by the led.value() function.


sParam = sASCII.split(' ')
if sParam[0] == 'GPOUT':
pin = int(sParam[1])
val = int(sParam[2])
led = machine.Pin(pin, machine.Pin.OUT)
led.value(val)

The Python source code of the TCP Client (TCPClient.py) running on the PC is shown in Listing
4.

Listing 4.

import sys
import socket
if (len(sys.argv) == 4):
gpio = str(sys.argv[1])
pin = str(sys.argv[2])
state = str(sys.argv[3])
cmd = gpio + ' ' + pin + ' ' + state
# create a socket object

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "192.168.0.107"; # IP-address of the TCP server of NodeMCU
port = 55000
# connection to hostname on the port.
s.connect((host, port))
s.send(cmd.encode('utf8')) # utf-8 coding is used
sRecv = s.recv(128)
s.close()
print('Echo Received: ' + sRecv.decode('utf8'))


To configure our system, we should download the source code of a TCP server into ESP8266
using the ampy utility:


$ ampy --port /dev/ttyUSB0 put TCPServer.py /main.py

In the above command, the TCPServer.py file contains the source code shown in Listing 4.
Then we reset the ESP8266 board and test it.

When testing the TCP Server, we will drive pins GPIO16 and GPIO5 on the ESP8266 board.
GPIO16 is connected to the on-board LED with a pull-up resistor and GPIO5 is connected to
our LED (see Fig.6). To drive both pins ON/OFF we can use the following commands running in
the Ubuntu command prompt:

$ python TCPClient.py GPOUT 5 1
Echo Received: GPOUT 5 1
$ python TCPClient.py GPOUT 16 0
Echo Received: GPOUT 16 0
$ python TCPClient.py GPOUT 5 0
Echo Received: GPOUT 5 0
$ python TCPClient.py GPOUT 16 1
Echo Received: GPOUT 16 1

Note that the LED on pin GPIO16 is ON when the pin is LOW and OFF when GPIO16 is HIGH.

Driving digital outputs: project 2

In this project, the TCP Server is launched on ESP8266 by the ampy utility. The main.py file in
the root directory of ESP8266 should contain only the code for initializing Wi-Fi interface
(Listing 5).

Listing 5.
import network
sta_if = network.WLAN(network.STA_IF)
ap_if = network.WLAN(network.AP_IF)
ap_if.active(False)
if not sta_if.isconnected():
sta_if.active(True)
sta_if.connect('TP-LINK_77D8', 'password') # connect to my Wi-Fi network

The MicroPython source code of the TCP Server application is shown in Listing 6.
Listing 6.
import machine
import socket

# create a socket object
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

host = '192.168.0.107'
port = 55000

# bind to the port
serverSocket.bind((host, port))

# queue up to 5 requests
serverSocket.listen(5)

while True:
# establish a connection
clientSocket,addr = serverSocket.accept()
sRecv = clientSocket.recv(128)
sASCII = sRecv.decode('utf8')
sParam = sASCII.split(' ')
if sParam[0] == 'GPOUT':
pin = int(sParam[1])
val = int(sParam[2])
led = machine.Pin(pin, machine.Pin.OUT)
led.value(val)
clientSocket.send(sRecv)
clientSocket.close()

After saving the above code in the TCPServer.py file, the application can be launched on the
ESP8266 board by invoking the ampy utility:
$ ampy --port /dev/ttyUSB0 run TCPServer.py

The source code of the TCP Client is the same as that in the previous project. Note that after
exiting the TCP Server application (by pressing Ctrl-C), you should reset the ESP8266 board
before executing the same application one more time. Otherwise, you will get an EADDRINUSE
error message as is shown below:

$ ampy --port /dev/ttyUSB0 run mainTCPServer_GPOUT2.py
^C
Aborted!
$ ampy --port /dev/ttyUSB0 run mainTCPServer_GPOUT2.py
. . .
\nOSError: [Errno 98] EADDRINUSE\r\n')

Driving digital outputs: project 3
This project illustrates how to implement driving GPIO pins of ESP8266 through the WebREPL
interface. In this case, the source code of the TCP Server can be entered and executed within a
WebREPL window as is shown below:

>>> import socket
>>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> host = '192.168.0.107'
>>> port = 55000
>>> s.bind((host, port))
>>> s.listen(5)
>>> while True:
... cl,addr = s.accept()
... sRecv = cl.recv(128)
... sASCII = sRecv.decode('utf8')
... sParam = sASCII.split(' ')
... if sParam[0] == 'GPOUT':
... pin = int(sParam[1])
... val = int(sParam[2])
... led = machine.Pin(pin, machine.Pin.OUT)
... led.value(val)
... cl.send(sRecv)
... cl.close()
...


Programming PWM

This project illustrates configuring the duty cycle of a PWM signal on pin GPIO5 of the ESP8266
board.
The MicroPython source code of the TCP Server that will run on ESP8266 is shown in Listing 7.

Listing 7.

from machine import Pin, PWM
import time
import network
import socket

sta_if = network.WLAN(network.STA_IF)
ap_if = network.WLAN(network.AP_IF)
ap_if.active(False)
if not sta_if.isconnected():
sta_if.active(True)
sta_if.connect('TP-LINK_77D8', 'password')

time.sleep(2)
pwm5 = PWM(Pin(5), freq=500, duty=512)

# create a socket object
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

host = '192.168.0.107'
port = 55000

# bind to the port
serverSocket.bind((host, port))

# queue up to 5 requests
serverSocket.listen(5)

while True:
# establish a connection
clientSocket, addr = serverSocket.accept()
sRecv = clientSocket.recv(128)
sASCII = sRecv.decode('utf8')
sParam = sASCII.split(' ')
if sParam[0] == 'PWM':
pwmPin = int(sParam[1])
dutyCycle = int(sParam[2])
pwm5 = PWM(Pin(pwmPin), freq=500, duty=dutyCycle)
clientSocket.send(sRecv)
clientSocket.close()

In this source code, the sequence

sta_if = network.WLAN(network.STA_IF)
ap_if = network.WLAN(network.AP_IF)
ap_if.active(False)
if not sta_if.isconnected():
sta_if.active(True)
sta_if.connect('TP-LINK_77D8', 'password') # connect to my Wi-Fi network

puts the NodeMCU in the “station” mode and establishes the connection to the Wi-Fi network.
Once the board is connected to Wi-Fi, the network interface of NodeMCU is assigned the IP
address 192.168.0.107. This address will be used for configuring the TCP Server.
The sequence

serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = '192.168.0.107'
port = 55000
serverSocket.bind((host, port))
serverSocket.listen(5)

creates the server socket object serverSocket associated with the IP-address 192.1168.0.107
and port 55000. The TCP server will wait for incoming requests (max = 5) on this (“listening”)
socket.
The client requests are processed in the endless while loop. After the client connection is
accepted, the new “working” socket is created by the command:

clientSocket, addr = serverSocket.accept()


All operations with the client will then be performed using the clientSocket socket. In our case,
the clientSocket receives the command string from the TCP client and saves the data in the string
variable aASCII:

sRecv = clientSocket.recv(128)
sASCII = sRecv.decode('utf8')

The following sequence parses the sASCII string, determines the output to drive (the pwmPin
variable), then determines the duty cycle to be written to this pin (the dutyCycle variable). The
pin to drive is kept in the pwm5 variable. Finally, the value of dutyCycle will be written to the
pin by calling the PWM() function.

sParam = sASCII.split(' ')
if sParam[0] == 'PWM':
pwmPin = int(sParam[1])
dutyCycle = int(sParam[2])
pwm5 = PWM(Pin(pwmPin), freq=500, duty=dutyCycle)


The Python source code of the TCP Client application running in Ubuntu is shown in Listing 8.

Listing 8.

import sys
import socket
if (len(sys.argv) == 4):
pwm = str(sys.argv[1])
pin = str(sys.argv[2])
duty = str(sys.argv[3])
cmd = pwm + ' ' + pin + ' ' + duty
# create a socket object

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "192.168.0.107"; # IP-address of the TCP server of NodeMCU
port = 55000
# connection to hostname on the port.
s.connect((host, port))
s.send(cmd.encode('utf8')) # utf-8 coding is used
sRecv = s.recv(128)
s.close()
print('Echo Received:' + sRecv.decode('utf8'))


Reading analog signals: project 1

This project illustrates measuring an analog signal on pin A0 of ESP8266 and transferring the
data obtained to a remote TCP Client. To test an application, we use the circuit shown in Fig.7.


Fig.7


In this circuit, the analog signal on pin A0 is simulated by the voltage divider arranged using
resistor R1 and potentiometer R2. Note that the analog voltage on pin A0 of ESP8266 must
not exceed 1.0 V!
The MicroPython source code of the TCP Server application running on ESP8266 is shown in
Listing 9.

Listing 9.

from machine import ADC
import time
import network
import socket

sta_if = network.WLAN(network.STA_IF)
ap_if = network.WLAN(network.AP_IF)
ap_if.active(False)
if not sta_if.isconnected():
sta_if.active(True)
sta_if.connect('TP-LINK_77D8', 'password') # connect to my Wi-Fi network

time.sleep(2)

LSB = 3.3/1024 # LSB for ADC
adc = ADC(0) # ADC object

# create a socket object
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

host = '192.168.0.101'
port = 55000

# bind to the port
serverSocket.bind((host, port))

# queue up to 5 requests
serverSocket.listen(5)

while True:
# establish a connection
clientSocket,addr = serverSocket.accept()
sRecv = clientSocket.recv(128).decode('utf8')
if sRecv == 'ADC0':
Dn = adc.read()
vin = LSB * Dn
sVin = "{:.3f}".format(vin)
else:
sVin = 'Wrong parameter.'
clientSocket.send(sVin)
clientSocket.close()

In this source code, the binary code corresponding to the analog input voltage on pin A0 is taken
by the adc.read() command. The value of the code is saved in the Dn variable. The actual voltage
is represented as a float value and is kept in the vin variable. The string sVin contains the text
representation of vin. This string is then sent to the remote TCP Client by calling the
clientSocket.send(sVin) function.

The Python source code of a TCP Client (TCPClient.py) running on the PC is shown in Listing
10.

Listing 10.

import sys
import socket
if (len(sys.argv) == 2):
adc = str(sys.argv[1])
# create a socket object

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "192.168.0.101"; # IP-address of the TCP server of NodeMCU
port = 55000
# connection to hostname on the port.
s.connect((host, port))
s.send(adc.encode('utf8')) # utf-8 coding is used
sRecv = s.recv(128)
s.close()
print('Vin on A0, V: ' + sRecv.decode('utf8'))

The following command line allows to receive data from the TCP Server:

$ python TCPClient.py ADC0
Vin on A0, V: 0.387
$ python TCPClient.py ADC0
Vin on A0, V: 0.441
$ python TCPClient.py ADC2
Vin on A0, V: Wrong parameter.
$ python TCPClient.py ADC0
Vin on A0, V: 0.690


Reading analog signals: project 2

This is a modified version of the previous project. Here the TCP server application runs on the
PC, while the TCP Client application running on the ESP8266 board periodically measures the
analog voltage on pin A0 and sends the result to the remote TCP Server.

The MicroPython source code of the TCP client running on the ESP8266 board is shown in
Listing 11.

Listing 11.

from machine import ADC
import time
import socket

LSB = 3.3/1024 # LSB for ADC
adc = ADC(0) # ADC object

host = "192.168.0.100" #the IP-address of the PC
port = 55000
cnt = 0

while cnt < 15:
# create a socket object
sClient = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# connection to hostname on the port.
sClient.connect((host, port))
Dn = adc.read()
vin = LSB * Dn
sClient.send((str(cnt+1) +':Voltage on pin A0, V = ' +
'{:.3f}'.format(vin)).encode('utf8')) # utf-8 coding is used
sClient.close()
time.sleep(10)
cnt += 1

In this source code, the program code within a while() loop repeats until a counter cnt reaches
15.
This code can be inserted in the main.py file to run while ESP8266 is powered on or reset. In this
example, the above code is put in the TCPClient.py file and starts running on the ESP8266 board
by using the ampy command:

$ ampy --port /dev/ttyUSB0 run TCPClient.py

The TCP Server (TCPServer.py) running on the PC receives the results of measurements. The
Server’s source code is shown in Listing 12.

Listing 12.

import socket

# create a socket object
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

host = "192.168.0.100"
port = 55000

# bind to the port
serverSocket.bind((host, port))

# queue up to 5 requests
serverSocket.listen(5)
print("TCP Server waits for incoming requests on
192.168.0.100:55000...")
try:
while True:
# establish a connection
clientSocket,addr = serverSocket.accept()
sRecv = clientSocket.recv(256)
clientSocket.close()
print(sRecv.decode('utf8'))
except KeyboardInterrupt:
serverSocket.close()
print('TCP Server is shutting down…')

The TCP server application produces the following output:

$ python TCPServer.py
TCP Server waits for incoming requests on 192.168.0.100:55000...
1:Voltage on pin A0, V = 0.135
2:Voltage on pin A0, V = 0.168
3:Voltage on pin A0, V = 0.873
4:Voltage on pin A0, V = 0.725
5:Voltage on pin A0, V = 0.738
6:Voltage on pin A0, V = 0.206
7:Voltage on pin A0, V = 0.200
8:Voltage on pin A0, V = 0.429
9:Voltage on pin A0, V = 0.487
10:Voltage on pin A0, V = 0.503
11:Voltage on pin A0, V = 0.699
12:Voltage on pin A0, V = 0.960
13:Voltage on pin A0, V = 0.951
14:Voltage on pin A0, V = 0.970
15:Voltage on pin A0, V = 0.983

Reading analog signals using a Web Server

This project illustrates measuring analog input voltage on pin A0 of ESP8266 using a simple
HTTP (Web) Server running on the board. We can read the value of an analog input signal by
entering an IP-address/port pair in the address field of a Web browser running somewhere on a
network.

In such configurations, the Wi-Fi board runs a Web (HTTP) server that is a special case of a TCP
server, because a HTTP protocol is based on a TCP protocol suite. A Web browser (Google
Chrome, in our example) will send/receive data to/from a HTTP server. In fact, a Web-browser is
a TCP client that sends requests based upon HTTP protocol specifications to the HTTP server.
Using a Web browser saves a lot of time, especially in simple wireless systems, since we don't
need to write any client source code any more.

We will not consider the HTTP protocol in depth; you can find numerous documents, literature
and tutorials on this topic on the Internet. We will only discuss practical aspects of designing
"Web (HTTP) server – Web browser" wireless network systems using NodeMCU and the PC. A
very simple network configuration is shown in Fig.8.

Fig.8

In the above Wi-Fi network configuration, the NodeMCU Wi-Fi board runs a Web (HTTP) server,
while the desktop PC/notebook runs the Web browser.

The MicroPython source code of the HTTP Server is shown in Listing 13.

Listing 13.

from machine import Pin
import socket

pinNum = [5,4,0]
pins = ['pin5','pin4','pin0']
state = [0,0,0]

for i in range(0,3):
pins[i] = Pin(pinNum[i], Pin.IN, Pin.PULL_UP)

addr = ('192.168.0.107', 8081)

serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serverSocket.bind(addr)
serverSocket.listen(3)

while True:
cl, addr = serverSocket.accept()
cl_file = cl.makefile('rwb', 0)
while True:
line = cl_file.readline()
if not line or line == b'\r\n':
break
sInp = ''
for i in range(0,3):
state[i] = pins[i].value()
sInp += str(state[i])

# Prepare the response
response = 'HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n'
response += """<!DOCTYPE html>
<html>
<body>
<h3>State of ESP8266 Pins [5:4:0] = [%s] </h3>
</body>
</html>\n""" % sInp

# Send the response to the client
cl.send(response)
cl.close()

Save the above code in the HTTPServer.py file and launch the application by invoking the ampy
utility as is shown below:

$ ampy --port /dev/ttyUSB0 run HTTPServer.py

To read the input A0 on the remote ESP8266 board, we should enter “192.168.0.107:8081” in the
address field of a Web browser. This is illustrated in Fig.9.


Fig.9

Alternatively, we can put the source code of the HTTP Server in the main.py file and write the
file in the flash memory of ESP8266. In this case, the MicroPython source code of the main.py
file on the ESP8266 board will look like the following (Listing 14).

Listing 14.

from machine import ADC
import socket
import network
import time

sta_if = network.WLAN(network.STA_IF)
ap_if = network.WLAN(network.AP_IF)
ap_if.active(False)
if not sta_if.isconnected():
sta_if.active(True)
sta_if.connect('TP-LINK_77D8', 'password') # connect to my Wi-Fi network

time.sleep(2)


LSB = 3.3/1024 # LSB for ADC
adc = ADC(0) # ADC object

addr = ('192.168.0.107',8081)

serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serverSocket.bind(addr)
serverSocket.listen(3)

while True:
cl, addr = serverSocket.accept()
cl_file = cl.makefile('rwb', 0)
while True:
line = cl_file.readline()
if not line or line == b'\r\n':
break
Dn = adc.read()
vin = LSB * Dn
sVin = "{:.3f}".format(vin)

# Prepare the response
response = 'HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n'
response += """<!DOCTYPE html>
<html>
<body>
<h3>Voltage on pin A0 = %sV </h3>
</body>
</html>\n""" % sVin

# Send the response to the client
cl.send(response)
cl.close()

To rewrite the main.py file in the root directory of ESP8266, we can use the ampy utility as is
shown below:

$ ampy --port /dev/ttyUSB0 put HTTPServer.py /main.py

After reset, the HTTP Server starts execution on the ESP8266 board.

Reading digital inputs: project 1

This project illustrates how to read digital signals on input pins of the ESP8266 board. In this
system, the TCP Server application runs on NodeMCU. The Server reads pins GPIO5 (“5”),
GPIO4 (“4”) and GPIO0 (“0”) configured as digital inputs with pull-up resistors. To test this
application, we can feed digital signals to these pins as is shown in Fig.10.


Fig.10

The MicroPython source code of the TCP Server is shown in Listing 15.

Listing 15.

from machine import Pin
import network
import socket
import time

sta_if = network.WLAN(network.STA_IF)
ap_if = network.WLAN(network.AP_IF)
ap_if.active(False)
if not sta_if.isconnected():
sta_if.active(True)
sta_if.connect('TP-LINK_77D8', 'password') # connect to my Wi-Fi network

time.sleep(2)

pinNum = [5,4,0]
pins = ['pin5','pin4','pin0']
state = [0,0,0]

for i in range(0,3):
pins[i] = Pin(pinNum[i], Pin.IN, Pin.PULL_UP)

# create a socket object
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

host = '192.168.0.101'
port = 55000

# bind to the port
serverSocket.bind((host, port))

# queue up to 5 requests
serverSocket.listen(5)

while True:
# establish a connection
clientSocket,addr = serverSocket.accept()
sRecv = clientSocket.recv(128)
sASCII = sRecv.decode('utf8')
if sASCII == 'GPIN':
s1 = ''
for i in range(0,3):
state[i] = pins[i].value()
s1 += str(state[i])
clientSocket.send(s1.encode('utf8'))
clientSocket.close()

Save this source code in TCPServer.py and rewrite the main.py file in the root directory of the
MicroPython file system using the ampy utility:

$ ampy --port /dev/ttyUSB0 put TCPServer.py /main.py

To start the application, you should reset the ESP8266 board.
The Python source code of the TCP client application running on the PC is shown in Listing 16.

Listing 16.

import sys
import socket
if (len(sys.argv) == 2):
adc = str(sys.argv[1])
# create a socket object

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "192.168.0.101"; # IP-address of the TCP server of NodeMCU
port = 55000
# connection to hostname on the port.
s.connect((host, port))
s.send(adc.encode('utf8')) # utf-8 coding is used
sRecv = s.recv(512)
s.close()
print('Inputs[5-4-0]=[' + sRecv.decode('utf8') + ']')

Save the above code in the TCPClient.py file. The command line and output produced by the
TCP Client application is shown below (the TCP Server on ESP8266 should already be running):

$ python TCPClient.py GPIN
Inputs[5-4-0]=[101]
$ python TCPClient.py GPIN
Inputs[5-4-0]=[100]
$ python TCPClient.py GPIN
Inputs[5-4-0]=[010]

Reading digital inputs: project 2

In this project, reading digital inputs 5-4-0 of the ESP8266 board is performed by a TCP client
which periodically (every 5 s) sends data obtained to a TCP Server running on the PC with an IP-
address 192.168.0.100. The TCP server waits for incoming requests on port 55000.
The Python source code of the TCP Server (TCPServer.py) is shown in Listing 17.

Listing 17.

import socket
# create a socket object
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

host = "192.168.0.100"
port = 55000

# bind to the port
serverSocket.bind((host, port))

# queue up to 5 requests
serverSocket.listen(5)
print("TCP Server waits for incoming requests on
192.168.0.100:55000...")
try:
while True:
# establish a connection
clientSocket,addr = serverSocket.accept()
sRecv = clientSocket.recv(512)
clientSocket.close()
print('Inputs[5-4-0] = [' + sRecv.decode('utf8') + ']')
except KeyboardInterrupt:
serverSocket.close()
print('TCP Server is shutting down…')

The MicroPython source code of the TCP Client (TCPClient.py) that should run on the ESP8266
board is shown in Listing 18.

Listing 18.

from machine import Pin
import socket
import time

pinNum = [5,4,0]
pins = ['pin5','pin4','pin0']
state = [0,0,0]

for i in range(0,3):
pins[i] = Pin(pinNum[i], Pin.IN, Pin.PULL_UP)

host = '192.168.0.100'
port = 55000
cnt = 0

while cnt < 10: # 10 measurements
# create a socket object
clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# establish a connection
clientSocket.connect((host, port))
s1 = ''
for i in range(0,3):
state[i] = pins[i].value()
s1 += str(state[i])
clientSocket.send(s1.encode('utf8'))
clientSocket.close()
time.sleep(5)
cnt += 1

To test this system, we should first launch the TCP Server on the PC, then run the TCP Client on
ESP8266 by executing the ampy command:

$ ampy --port /dev/ttyUSB0 run mainTCPClient.py

The TCP Server will produce the following output:

$ python TCPServer.py
TCP Server waits for incoming requests on 192.168.0.100:55000...
Inputs[5-4-0] = [011]
Inputs[5-4-0] = [011]
Inputs[5-4-0] = [011]
Inputs[5-4-0] = [011]
Inputs[5-4-0] = [010]
Inputs[5-4-0] = [010]
Inputs[5-4-0] = [110]
Inputs[5-4-0] = [110]
Inputs[5-4-0] = [100]
Inputs[5-4-0] = [100]
Inputs[5-4-0] = [100]

Reading digital inputs using a Web Server

It is possible to read digital input pins 5,4 and 0 using a HTTP (Web) server that runs on the
ESP8266 board with an IP-address 192.168.0.107. The HTTP Server waits for incoming requests
on port 8080.
The MicroPython source code of the HTTP server (HTTPServer.py) is shown in Listing 19.

Listing 19.

from machine import Pin
import socket

pinNum = [5,4,0]
pins = ['pin5','pin4','pin0']
state = [0,0,0]

for i in range(0,3):
pins[i] = Pin(pinNum[i], Pin.IN, Pin.PULL_UP)

addr = ('192.168.0.107',8080)

serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serverSocket.bind(addr)
serverSocket.listen(3)

while True:
cl, addr = serverSocket.accept()
cl_file = cl.makefile('rwb', 0)
while True:
line = cl_file.readline()
if not line or line == b'\r\n':
break
sInp = ''
for i in range(0,3):
state[i] = pins[i].value()
sInp += str(state[i])

# Prepare the response
response = 'HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n'
response += """<!DOCTYPE html>
<html>
<body>
<h3>State of ESP8266 Pins [5:4:0] = [%s] </h3>
</body>
</html>\n""" % sInp

# Send the response to the client
cl.send(response)
cl.close()

To start HTTP Server on ESP8266, we should use the ampy utility as is shown below:

$ ampy --port /dev/ttyUSB0 run HTTPServer.py

Note that if you terminate this application by pressing Ctrl-C, we need to reset the ESP8266
board before launching the HTTP Server one more time.
The Web browser provides the following output (Fig.11).


Fig.11

It is possible to put the source code of the HTTP Server (HTTPServer.py) in the main.py file in
the root directory of a MicroPython file system so that our server will start off each time the
ESP8266 board is powered/reset.
The MicroPython source code of the HTTP Server will look like the following (Listing 20).

Listing 20.

from machine import Pin
import socket
import network
import time

sta_if = network.WLAN(network.STA_IF)
ap_if = network.WLAN(network.AP_IF)
ap_if.active(False)
if not sta_if.isconnected():
sta_if.active(True)
sta_if.connect('TP-LINK_77D8', 'password') #connect to my home Wi-Fi network

time.sleep(2)

pinNum = [5,4,0]
pins = ['pin5','pin4','pin0']
state = [0,0,0]

for i in range(0,3):
pins[i] = Pin(pinNum[i], Pin.IN, Pin.PULL_UP)

addr = ('192.168.0.107',8080)

serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serverSocket.bind(addr)
serverSocket.listen(3)

while True:
cl, addr = serverSocket.accept()
cl_file = cl.makefile('rwb', 0)
while True:
line = cl_file.readline()
if not line or line == b'\r\n':
break
sInp = ''
for i in range(0,3):
state[i] = pins[i].value()
sInp += str(state[i])

# Prepare the response
response = 'HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n'
response += """<!DOCTYPE html>
<html>
<body>
<h3>State of ESP8266 Pins [5:4:0] = [%s] </h3>
</body>
</html>\n""" % sInp

# Send the response to the client
cl.send(response)
cl.close()

Writing this file to ESP8266 may be accomplished by the ampy program:

$ ampy --port /dev/ttyUSB0 put HTTPServer.py /main.py

After writing is complete, reset the ESP8266 board to start the HTTP Server.

Das könnte Ihnen auch gefallen