summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--docs/esp8266/tutorial/adc.rst19
-rw-r--r--docs/esp8266/tutorial/filesystem.rst70
-rw-r--r--docs/esp8266/tutorial/index.rst28
-rw-r--r--docs/esp8266/tutorial/intro.rst95
-rw-r--r--docs/esp8266/tutorial/neopixel.rst70
-rw-r--r--docs/esp8266/tutorial/network_basics.rst81
-rw-r--r--docs/esp8266/tutorial/network_tcp.rst121
-rw-r--r--docs/esp8266/tutorial/nextsteps.rst12
-rw-r--r--docs/esp8266/tutorial/onewire.rst37
-rw-r--r--docs/esp8266/tutorial/pins.rst75
-rw-r--r--docs/esp8266/tutorial/powerctrl.rst61
-rw-r--r--docs/esp8266/tutorial/pwm.rst87
-rw-r--r--docs/esp8266/tutorial/repl.rst205
13 files changed, 960 insertions, 1 deletions
diff --git a/docs/esp8266/tutorial/adc.rst b/docs/esp8266/tutorial/adc.rst
new file mode 100644
index 0000000000..fa6fdaba73
--- /dev/null
+++ b/docs/esp8266/tutorial/adc.rst
@@ -0,0 +1,19 @@
+Analog to Digital Conversion
+============================
+
+The ESP8266 has a single pin (separate to the GPIO pins) which can be used to
+read analog voltages and convert them to a digital value. You can construct
+such an ADC pin object using::
+
+ >>> import machine
+ >>> adc = machine.ADC(0)
+
+Then read its value with::
+
+ >>> adc.read()
+ 58
+
+The values returned from the ``read()`` function are between 0 (for 0.0 volts)
+and 1024 (for 1.0 volts). Please note that this input can only tolerate a
+maximum of 1.0 volts and you must use a voltage divider circuit to measure
+larger voltages.
diff --git a/docs/esp8266/tutorial/filesystem.rst b/docs/esp8266/tutorial/filesystem.rst
new file mode 100644
index 0000000000..9033a8576f
--- /dev/null
+++ b/docs/esp8266/tutorial/filesystem.rst
@@ -0,0 +1,70 @@
+The internal filesystem
+=======================
+
+If your devices has 1Mbyte or more of storage then it will be set up (upon first
+boot) to contain a filesystem. This filesystem uses the FAT format and is
+stored in the flash after the MicroPython firmware.
+
+Creating and reading files
+--------------------------
+
+MicroPython on the ESP8266 supports the standard way of accessing files in
+Python, using the built-in ``open()`` function.
+
+To create a file try::
+
+ >>> f = open('data.txt', 'w')
+ >>> f.write('some data')
+ 9
+ >>> f.close()
+
+The "9" is the number of bytes that were written with the ``write()`` method.
+Then you can read back the contents of this new file using::
+
+ >>> f = open('data.txt')
+ >>> f.read()
+ 'some data'
+ >>> f.close()
+
+Note that the default mode when opening a file is to open it in read-only mode,
+and as a text file. Specify ``'wb'`` as the second argument to ``open()`` to
+open for writing in binary mode, and ``'rb'`` to open for reading in binary
+mode.
+
+Listing file and more
+---------------------
+
+The os module can be used for further control over the filesystem. First
+import the module::
+
+ >>> import os
+
+Then try listing the contents of the filesystem::
+
+ >>> os.listdir()
+ ['boot.py', 'port_config.py', 'data.txt']
+
+You can make directories::
+
+ >>> os.mkdir('dir')
+
+And remove entries::
+
+ >>> os.remove('data.txt')
+
+Start up scripts
+----------------
+
+There are two files that are treated specially by the ESP8266 when it starts up:
+boot.py and main.py. The boot.py script is executed first (if it exists) and
+then once it completes the main.py script is executed. You can create these
+files yourself and populate them with the code that you want to run when the
+device starts up.
+
+Accessing the filesystem via WebREPL
+------------------------------------
+
+You can access the filesystem over WebREPL using the provided command-line
+tool. This tool is found at `<https://github.com/micropython/webrepl>`__
+and is called webrepl_cli.py. Please refer to that program for information
+on how to use it.
diff --git a/docs/esp8266/tutorial/index.rst b/docs/esp8266/tutorial/index.rst
index 7a68e9dc47..1a00afd853 100644
--- a/docs/esp8266/tutorial/index.rst
+++ b/docs/esp8266/tutorial/index.rst
@@ -3,4 +3,30 @@
MicroPython tutorial for ESP8266
================================
-TBD
+This tutorial is intended to get you started using MicroPython on the ESP8266
+system-on-a-chip. If it is your first time it is recommended to follow the
+tutorial through in the order below. Otherwise the sections are mostly self
+contained, so feel free to skip to those that interest you.
+
+The tutorial does not assume that you know Python, but it also does not attempt
+to explain any of the details of the Python language. Instead it provides you
+with commands that are ready to run, and hopes that you will gain a bit of
+Python knowledge along the way. To learn more about Python itself please refer
+to `<https://www.python.org>`__.
+
+.. toctree::
+ :maxdepth: 1
+ :numbered:
+
+ intro.rst
+ repl.rst
+ filesystem.rst
+ network_basics.rst
+ network_tcp.rst
+ pins.rst
+ pwm.rst
+ adc.rst
+ powerctrl.rst
+ onewire.rst
+ neopixel.rst
+ nextsteps.rst
diff --git a/docs/esp8266/tutorial/intro.rst b/docs/esp8266/tutorial/intro.rst
new file mode 100644
index 0000000000..2db2ba5bd5
--- /dev/null
+++ b/docs/esp8266/tutorial/intro.rst
@@ -0,0 +1,95 @@
+Introduction to MicroPython on the ESP8266
+==========================================
+
+Using MicroPython is a great way to get the most of your ESP8266 board. And
+vice versa, the ESP8266 chip is a great platform for using MicroPython. This
+tutorial will guide you through setting up MicroPython, getting a prompt, using
+WebREPL, connecting to the network and communicating with the Internet, using
+the hardware peripherals, and controlling some external components.
+
+Let's get started!
+
+Requirements
+------------
+
+The first thing you need is a board with an ESP8266 chip. The MicroPython
+software supports the ESP8266 chip itself and any board should work. The main
+characteristic of a board is how much flash it has, how the GPIO pins are
+connected to the outside world, and whether it includes a built-in USB-serial
+convertor to make the UART available to your PC.
+
+The minimum requirement for flash size is 512k. A board with this amount of
+flash will not have room for a filesystem, but otherwise is fully functional.
+If your board has 1Mbyte or more of flash then it will support a filesystem.
+
+Names of pins will be given in this tutorial using the chip names (eg GPIO0)
+and it should be straightforward to find which pin this corresponds to on your
+particular board.
+
+Powering the board
+------------------
+
+If your board has a USB connector on it then most likely it is powered through
+this when connected to your PC. Otherwise you will need to power it directly.
+Please refer to the documentation for your board for further details.
+
+Deploying the firmware
+----------------------
+
+The very first thing you need to do is put the MicroPython firmware (compiled
+code) on your ESP8266 device. There are two main steps to do this: first you
+need to put your device in boot-loader mode, and second you need to copy across
+the firmware. The exact procedure for these steps is highly dependent on the
+particular board and you will need to refer to its documentation for details.
+
+If you have a board that has a USB connector, a USB-serial convertor, and has
+the DTR and RTS pins wired in a special way then deploying the firmware should
+be easy as all steps can be done automatically. Boards that have such features
+include the Adafruit Feather HUZZAH and NodeMCU boards.
+
+For best results it is recommended to first erase the entire flash of your
+device before putting on new MicroPython firmware.
+
+Currently we only support esptool.py to copy across the firmware. You can find
+this tool here: `<https://github.com/themadinventor/esptool/>`__ . Any other
+flashing program should work, so feel free to try them out, or refer to the
+documentation for your board to see its recommendations.
+
+Using esptool.py you can erase the flash with the command::
+
+ esptool.py --port /dev/ttyUSB0 erase_flash
+
+And then deploy the new firmware using::
+
+ esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=8m 0 mp-esp8266-firmware.bin
+
+You might need to change the "port" setting to something else relevant for your
+PC. You may also need to reduce the baudrate if you get errors when flashing
+(eg down to 115200).
+
+If you have a NodeMCU board, you may need to use the following command to deploy
+the firmware (note the "-fm dio" option)::
+
+ esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=8m -fm dio 0 mp-esp8266-firmware.bin
+
+If the above commands run without error then MicroPython should be installed on
+your board!
+
+Serial prompt
+-------------
+
+Once you have the firmware on the device you can access the REPL (Python prompt)
+over UART0 (GPIO1=TX, GPIO3=RX), which might be connected to a USB-serial
+convertor, depending on your board. The baudrate is 115200. The next part of
+the tutorial will discuss the prompt in more detail.
+
+WiFi
+----
+
+After a fresh install and boot the device configures itself as a WiFi access
+point (AP) that you can connect to. The ESSID is of the form MicroPython-xxxxxx
+where the x's are replaced with part of the MAC address of your device (so will
+be the same everytime, and most likely different for all ESP8266 chips). The
+password for the WiFi is micropythoN (note the upper-case N). Its IP address
+will be 192.168.4.1 once you connect to its network. WiFi configuration will
+be discussed in more detail later in the tutorial.
diff --git a/docs/esp8266/tutorial/neopixel.rst b/docs/esp8266/tutorial/neopixel.rst
new file mode 100644
index 0000000000..245aed6d46
--- /dev/null
+++ b/docs/esp8266/tutorial/neopixel.rst
@@ -0,0 +1,70 @@
+Controlling NeoPixels
+=====================
+
+NeoPixels, also known as WS2812 LEDs, are full-colour LEDs that are connected in
+serial, are individually addressable, and can have their red, green and blue
+components set between 0 and 255. They require precise timing to control them
+and there is a special neopixel module to do just this.
+
+To create a NeoPixel object do the following::
+
+ >>> import machine, neopixel
+ >>> np = neopixel.NeoPixel(machine.Pin(4), 8)
+
+This configures a NeoPixel strip on GPIO4 with 8 pixels. You can adjust the
+"4" (pin number) and the "8" (number of pixel) to suit your set up.
+
+To set the colour of pixels use::
+
+ >>> np[0] = (255, 0, 0) # set to red, full brightness
+ >>> np[1] = (0, 128, 0) # set to green, half brightness
+ >>> np[2] = (0, 0, 64) # set to blue, quarter brightness
+
+Then use the ``write()`` method to output the colours to the LEDs::
+
+ >>> np.write()
+
+The following demo function makes a fancy show on the LEDs::
+
+ import time
+
+ def demo(np):
+ n = np.n
+
+ # cycle
+ for i in range(4 * n):
+ for j in range(n):
+ np[j] = (0, 0, 0)
+ np[i % n] = (255, 255, 255)
+ np.write()
+ time.sleep_ms(25)
+
+ # bounce
+ for i in range(4 * n):
+ for j in range(n):
+ np[j] = (0, 0, 128)
+ if (i // n) % 2 == 0:
+ np[i % n] = (0, 0, 0)
+ else:
+ np[n - 1 - (i % n)] = (0, 0, 0)
+ np.write()
+ time.sleep_ms(60)
+
+ # fade in/out
+ for i in range(0, 4 * 256, 8):
+ for j in range(n):
+ if (i // 256) % 2 == 0:
+ val = i & 0xff
+ else:
+ val = 255 - (i & 0xff)
+ np[j] = (val, 0, 0)
+ np.write()
+
+ # clear
+ for i in range(n):
+ np[i] = (0, 0, 0)
+ np.write()
+
+Execute it using::
+
+ >>> demo(np)
diff --git a/docs/esp8266/tutorial/network_basics.rst b/docs/esp8266/tutorial/network_basics.rst
new file mode 100644
index 0000000000..02a7054858
--- /dev/null
+++ b/docs/esp8266/tutorial/network_basics.rst
@@ -0,0 +1,81 @@
+Network basics
+==============
+
+The network module is used to configure the WiFi connection. There are two WiFi
+interfaces, one for the station (when the ESP8266 connects to a router) and one
+for the access point (for other devices to connect to the ESP8266). Create
+instances of these objects using::
+
+ >>> import network
+ >>> sta_if = network.WLAN(network.STA_IF)
+ >>> ap_if = network.WLAN(network.AP_IF)
+
+You can check if the interfaces are active by::
+
+ >>> sta_if.active()
+ False
+ >>> ap_if.active()
+ True
+
+You can also check the network settings of the interface by::
+
+ >>> ap.ifconfig()
+ ('192.168.4.1', '255.255.255.0', '192.168.4.1', '8.8.8.8')
+
+The returned values are: IP address, netmask, gateway, DNS.
+
+Configuration of the WiFi
+-------------------------
+
+Upon a fresh install the ESP8266 is configured in access point mode, so the
+AP_IF interface is active and the STA_IF interface is inactive. You can
+configure the module to connect to your own network using the STA_IF interface.
+
+First activate the station interface::
+
+ >>> sta_if.active(True)
+
+Then connect to your WiFi network::
+
+ >>> sta_if.connect('<your ESSID>', '<your password>')
+
+To check if the connection is established use::
+
+ >>> sta_if.isconnected()
+
+Once established you can check the IP address::
+
+ >>> sta_if.ifconfig()
+ ('192.168.0.2', '255.255.255.0', '192.168.0.1', '8.8.8.8')
+
+You can then disable the access-point interface if you no longer need it::
+
+ >>> ap_if.active(False)
+
+Here is a function you can run (or put in your boot.py file) to automatically
+connect to your WiFi network::
+
+ 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 network.isconnected():
+ pass
+ print('network config:', sta_if.ifconfig())
+
+Sockets
+-------
+
+Once the WiFi is set up the way to access the network is by using sockets.
+A socket represents an endpoint on a network device, and when two sockets are
+connected together communication can proceed.
+Internet protocols are built on top of sockets, such as email (SMTP), the web
+(HTTP), telnet, ssh, among many others. Each of these protocols is assigned
+a specific port, which is just an integer. Given an IP address and a port
+number you can connect to a remote device and start talking with it.
+
+The next part of the tutorial discusses how to use sockets to do some common
+and useful network tasks.
diff --git a/docs/esp8266/tutorial/network_tcp.rst b/docs/esp8266/tutorial/network_tcp.rst
new file mode 100644
index 0000000000..0a1cca4457
--- /dev/null
+++ b/docs/esp8266/tutorial/network_tcp.rst
@@ -0,0 +1,121 @@
+Network - TCP sockets
+=====================
+
+The building block of most of the internet is the TCP socket. These sockets
+provide a reliable stream of bytes between the connected network devices.
+This part of the tutorial will show how to use TCP sockets in a few different
+cases.
+
+Star Wars Asciimation
+---------------------
+
+The simplest thing to do is to download data from the internet. In this case
+we will use the Star Wars Asciimation service provided by the blinkenlights.nl
+website. It uses the telnet protocol on port 23 to stream data to anyone that
+connects. It's very simple to use because it doesn't require you to
+authenticate (give a username or password), you can just start downloading data
+straight away.
+
+The first thing to do is make sure we have the socket module available::
+
+ >>> import socket
+
+Then get the IP address of the server::
+
+ >>> addr_info = socket.getaddrinfo("towel.blinkenlights.nl", 23)
+
+The ``getaddrinfo`` function actually returns a list of addresses, and each
+address has more information than we need. We want to get just the first valid
+address, and then just the IP address and port of the server. To do this use::
+
+ >>> addr = addr_info[0][-1]
+
+If you type ``addr_info`` and ``addr`` at the prompt you will see exactly what
+information they hold.
+
+Using the IP address we can make a socket and connect to the server::
+
+ >>> s = socket.socket()
+ >>> s.connect(addr[0][-1])
+
+Now that we are connected we can download and display the data::
+
+ >>> while True:
+ ... data = s.recv(500)
+ ... print(str(data, 'utf8'), end='')
+ ...
+
+When this loop executes it should start showing the animation (use ctrl-C to
+interrupt it).
+
+You should also be able to run this same code on your PC using normal Python if
+you want to try it out there.
+
+HTTP GET request
+----------------
+
+The next example shows how to download a webpage. HTTP uses port 80 and you
+first need to send a "GET" request before you can download anything. As part
+of the request you need to specify the page to retrieve.
+
+Let's define a function that can download and print a URL::
+
+ def http_get(url):
+ _, _, host, path = url.split('/', 3)
+ addr = socket.getaddrinfo(host, 80)[0][-1]
+ s = socket.socket()
+ s.connect(addr)
+ s.send(bytes('GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n' % (path, host), 'utf8'))
+ while True:
+ data = s.recv(100)
+ if data:
+ print(str(data, 'utf8'), end='')
+ else:
+ break
+
+Make sure that you import the socket module before running this function. Then
+you can try::
+
+ >>> http_get('http://micropython.org/ks/test.html')
+
+This should retrieve the webpage and print the HTML to the console.
+
+Simple HTTP server
+------------------
+
+The following code creates an simple HTTP server which serves a single webpage
+that contains a table with the state of all the GPIO pins::
+
+ import machine
+ pins = [machine.Pin(i, machine.Pin.IN) for i in (0, 2, 4, 5, 12, 13, 14, 15)]
+
+ html = """<!DOCTYPE html>
+ <html>
+ <head> <title>ESP8266 Pins</title> </head>
+ <body> <h1>ESP8266 Pins</h1>
+ <table border="1"> <tr><th>Pin</th><th>Value</th></tr> %s </table>
+ </body>
+ </html>
+ """
+
+ import socket
+ addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
+
+ s = socket.socket()
+ s.bind(addr)
+ s.listen(1)
+
+ print('listening on', addr)
+
+ while True:
+ cl, addr = s.accept()
+ print('client connected from', addr)
+ cl_file = cl.makefile('rwb', 0)
+ while True:
+ line = cl_file.readline()
+ if not line or line == b'\r\n':
+ break
+ rows = ['<tr><td>%s</td><td>%d</td></tr>' % (str(p), p.value()) for p in pins]
+ response = html % '\n'.join(rows)
+ cl.send(response)
+ cl.close()
diff --git a/docs/esp8266/tutorial/nextsteps.rst b/docs/esp8266/tutorial/nextsteps.rst
new file mode 100644
index 0000000000..318bd7ddf8
--- /dev/null
+++ b/docs/esp8266/tutorial/nextsteps.rst
@@ -0,0 +1,12 @@
+Next steps
+==========
+
+That brings us to the end of the tutorial! Hopefully by now you have a good
+feel for the capabilities of MicroPython on the ESP8266 and understand how to
+control both the WiFi and IO aspects of the chip.
+
+There are many features that were not covered in this tutorial. The best way
+to learn about them is to read the full documentation of the modules, and to
+experiment!
+
+Good luck creating your Internet of Things devices!
diff --git a/docs/esp8266/tutorial/onewire.rst b/docs/esp8266/tutorial/onewire.rst
new file mode 100644
index 0000000000..c90044b7a8
--- /dev/null
+++ b/docs/esp8266/tutorial/onewire.rst
@@ -0,0 +1,37 @@
+Controlling 1-wire devices
+==========================
+
+The 1-wire bus is a serial bus that uses just a single wire for communication
+(in addition to wires for ground and power). The DS18B20 temperature sensor
+is a very popular 1-wire device, and here we show how to use the onewire module
+to read from such a device.
+
+For the following code to work you need to have at least one DS18B20 temperature
+sensor with its data line connected to GPIO12. You must also power the sensors
+and connect a 4.7k Ohm resistor between the data pin and the power pin. ::
+
+ import time
+ import machine
+ import onewire
+
+ # the device is on GPIO12
+ dat = machine.Pin(12)
+
+ # create the onewire object
+ ds = onewire.DS18B20(onewire.OneWire(dat))
+
+ # scan for devices on the bus
+ roms = ds.scan()
+ print('found devices:', roms)
+
+ # loop 10 times and print all temperatures
+ for i in range(10):
+ print('temperatures:', end=' ')
+ ds.convert_temp()
+ time.sleep_ms(750)
+ for rom in roms:
+ print(ds.read_temp(rom), end=' ')
+ print()
+
+Note that you must execute the ``convert_temp()`` function to initiate a
+temperature reading, then wait at least 750ms before reading the value.
diff --git a/docs/esp8266/tutorial/pins.rst b/docs/esp8266/tutorial/pins.rst
new file mode 100644
index 0000000000..8ba4516273
--- /dev/null
+++ b/docs/esp8266/tutorial/pins.rst
@@ -0,0 +1,75 @@
+GPIO Pins
+=========
+
+The way to connect your board to the external world, and control other
+components, is through the GPIO pins. Not all pins are available to use,
+in most cases only pins 0, 2, 4, 5, 12, 13, 14, 15, and 16 can be used.
+
+The pins are available in the machine module, so make sure you import that
+first. Then you can create a pin using::
+
+ >>> pin = machine.Pin(0)
+
+Here, the "0" is the pin that you want to access. Usually you want to
+configure the pin to be input or output, and you do this when constructing
+it. To make an input pin use::
+
+ >>> pin = machine.Pin(0, machine.Pin.OUT, machine.Pin.PULL_UP)
+
+You can either use PULL_UP or PULL_NONE for the input pull-mode. If it's
+not specified then it defaults to PULL_NONE. You can read the value on
+the pin using::
+
+ >>> pin.value()
+ 0
+
+The pin on your board may return 0 or 1 here, depending on what it's connected
+to. To make an output pin use::
+
+ >>> pin = machine.Pin(0, machine.Pin.OUT)
+
+Then set its value using::
+
+ >>> pin.value(0)
+ >>> pin.value(1)
+
+Or::
+
+ >>> pin.low()
+ >>> pin.high()
+
+External interrupts
+-------------------
+
+All pins except number 16 can be configured to trigger a hard interrupt if their
+input changes. You can set code (a callback function) to be executed on the
+trigger.
+
+Let's first define a callback function, which must take a single argument,
+being the pin that triggered the function. We will make the function just print
+the pin::
+
+ >>> def callback(p):
+ ... print('pin change', p)
+
+Next we will create two pins and configure them as inputs::
+
+ >>> from machine import Pin
+ >>> p0 = Pin(0, Pin.IN)
+ >>> p2 = Pin(2, Pin.IN)
+
+An finally we need to tell the pins when to trigger, and the function to call
+when they detect an event::
+
+ >>> p0.irq(Pin.IRQ_FALLING, callback)
+ >>> p2.irq(Pin.IRQ_RISING | Pin.IRQ_FALLING, callback)
+
+We set pin 0 to trigger only on a falling edge of the input (when it goes from
+high to low), and set pin 2 to trigger on both a rising and falling edge. After
+entering this code you can apply high and low voltages to pins 0 and 2 to see
+the interrupt being executed.
+
+A hard interrupt will trigger as soon as the event occurs and will interrupt any
+running code, including Python code. As such your callback functions are
+limited in what they can do (they cannot allocate memory, for example) and
+should be as short and simple as possible.
diff --git a/docs/esp8266/tutorial/powerctrl.rst b/docs/esp8266/tutorial/powerctrl.rst
new file mode 100644
index 0000000000..9e44339c86
--- /dev/null
+++ b/docs/esp8266/tutorial/powerctrl.rst
@@ -0,0 +1,61 @@
+Power control
+=============
+
+The ESP8266 provides the ability to change the CPU frequency on the fly, and
+enter a deep-sleep state. Both can be used to manage power consumption.
+
+Changing the CPU frequency
+--------------------------
+
+The machine module has a function to get and set the CPU frequency. To get the
+current frequency use::
+
+ >>> import machine
+ >>> machine.freq()
+ 80000000
+
+By default the CPU runs at 80MHz. It can be change to 160MHz if you need more
+processing power, at the expense of current consumption::
+
+ >>> machine.freq(160000000)
+ >>> machine.freq()
+ 160000000
+
+You can change to the higher frequency just while your code does the heavy
+processing and then change back when its finished.
+
+Deep-sleep mode
+---------------
+
+The deep-sleep mode will shut down the ESP8266 and all its peripherals,
+including the WiFi (but not including the real-time-clock, which is used to wake
+the chip). This drastically reduces current consumption and is a good way to
+make devices that can run for a while on a battery.
+
+To be able to use the deep-sleep feature you must connect GPIO16 to the reset
+pin (RST on the Adafruit Feather HUZZAH board). Then the following code can be
+used to sleep and wake the device::
+
+ import machine
+
+ # configure RTC.ALARM0 to be able to wake the device
+ rtc = machine.RTC()
+ rtc.irq(trigger=rtc.ALARM0, wake=machine.DEEPSLEEP)
+
+ # set RTC.ALARM0 to fire after 10 seconds (waking the device)
+ rtc.alarm(rtc.ALARM0, 10000)
+
+ # put the device to sleep
+ machine.deepsleep()
+
+Note that when the chip wakes from a deep-sleep it is completely reset,
+including all of the memory. The boot scripts will run as usual and you can
+put code in them to check the reset cause to perhaps do something different if
+the device just woke from a deep-sleep. For example, to print the reset cause
+you can use::
+
+ if machine.reset_cause() == machine.DEEPSLEEP_RESET:
+ print('woke from a deep sleep')
+ else:
+ print('power on or hard reset')
+
diff --git a/docs/esp8266/tutorial/pwm.rst b/docs/esp8266/tutorial/pwm.rst
new file mode 100644
index 0000000000..8de509427c
--- /dev/null
+++ b/docs/esp8266/tutorial/pwm.rst
@@ -0,0 +1,87 @@
+Pulse Width Modulation
+======================
+
+Pulse width modulation (PWM) is a way to get an artificial analog output on a
+digital pin. It achieves this by rapidly toggling the pin from low to high.
+There are two parameters associated with this: the frequency of the toggling,
+and the duty cycle. The duty cycle is defined to be how long the pin is high
+compared with the length of a single period (low plus high time). Maximum
+duty cycle is when the pin is high all of the time, and minimum is when it is
+low all of the time.
+
+On the ESP8266 the pins 0, 2, 4, 5, 12, 13, 14 and 15 all support PWM. The
+limitation is that they must all be at the same frequency, and the frequency
+must be between 1Hz and 1kHz.
+
+To use PWM on a pin you must first create the pin object, for example::
+
+ >>> import machine
+ >>> p12 = machine.Pin(12)
+
+Then create the PWM object using::
+
+ >>> pwm12 = machine.PWM(p12)
+
+You can set the frequency and duty cycle using::
+
+ >>> pwm12.freq(500)
+ >>> pwm12.duty(512)
+
+Note that the duty cycle is between 0 (all off) and 1023 (all on), with 512
+being a 50% duty. If you print the PWM object then it will tell you its current
+configuration::
+
+ >>> pwm12
+ PWM(12, freq=500, duty=512)
+
+You can also call the ``freq()`` and ``duty()`` methods with no arguments to
+get their current values.
+
+The pin will continue to be in PWM mode until you deinitialise it using::
+
+ >>> pwm12.deinit()
+
+Fading an LED
+-------------
+
+Let's use the PWM feature to fade an LED. Assuming your board has an LED
+connected to pin 2 (ESP-12 modules do) we can create an LED-PWM object using::
+
+ >>> led = machine.PWM(machine.Pin(2), freq=1000)
+
+Notice that we can set the frequency in the PWM constructor.
+
+For the next part we will use timing and some math, so import these modules::
+
+ >>> import time, math
+
+Then create a function to pulse the LED::
+
+ >>> def pulse(l, t):
+ ... for i in range(20):
+ ... l.duty(int(math.sin(i / 10 * math.pi) * 500 + 500))
+ ... time.sleep_ms(t)
+
+You can try this function out using::
+
+ >>> pulse(led, 50)
+
+For a nice effect you can pulse many times in a row::
+
+ >>> for i in range(10):
+ ... pulse(led, 20)
+
+Remember you can use ctrl-C to interrupt the code.
+
+Control a hobby servo
+---------------------
+
+Hobby servo motors can be controlled using PWM. They require a frequency of
+50Hz and then a duty between about 40 and 115, with 77 being the centre value.
+If you connect a servo to the power and ground pins, and then the signal line
+to pin 12 (other pins will work just as well), you can control the motor using::
+
+ >>> servo = machine.PWM(machine.Pin(12), freq=50)
+ >>> servo.duty(40)
+ >>> servo.duty(115)
+ >>> servo.duty(77)
diff --git a/docs/esp8266/tutorial/repl.rst b/docs/esp8266/tutorial/repl.rst
new file mode 100644
index 0000000000..594adb3831
--- /dev/null
+++ b/docs/esp8266/tutorial/repl.rst
@@ -0,0 +1,205 @@
+Getting a MicroPython REPL prompt
+=================================
+
+REPL stands for Read Evaluate Print Loop, and is the name given to the
+interactive MicroPython prompt that you can access on the ESP8266. Using the
+REPL is by far the easiest way to test out your code and run commands.
+
+There are two ways to access the REPL: either via a wired connection through the
+UART serial port, or via WiFi.
+
+REPL over the serial port
+-------------------------
+
+The REPL is always available on the UART0 serial peripheral, which is connected
+to the pins GPIO1 for TX and GPIO3 for RX. The baudrate of the REPL is 115200.
+If your board has a USB-serial convertor on it then you should be able to access
+the REPL directly from your PC. Otherwise you will need to have a way of
+communicating with the UART.
+
+To access the prompt over USB-serial you need to use a terminal emulator program.
+On Windows TeraTerm is a good choice, on Mac you can use the built-in screen
+program, and Linux has picocom and minicom. Of course, there are many other
+terminal programs that will work, so pick your favourite!
+
+For example, on Linux you can try running::
+
+ picocom /dev/ttyUSB0
+
+Once you have made the connection over the serial port you can test if it is
+working by hitting enter a few times. You should see the Python REPL prompt,
+indicated by ``>>>``.
+
+WebREPL - a prompt over WiFi
+----------------------------
+
+WebREPL allows you to use the Python prompt over WiFi, connecting through a
+browser.
+
+The first thing you need to do is get the WebREPL client loaded in your
+favourite browser. The client can be found in the GitHub repository
+`<https://github.com/micropython/webrepl>`__ . It is called webrepl.html.
+The latest versions of Firefox and Chrome are supported.
+
+To use WebREPL connect your computer to the ESP8266's access point
+(MicroPython-xxxxxx, see the previous section about this). If you have
+already reconfigured your ESP8266 to connect to a router then you can
+skip this part.
+
+Once you are on the same network as the ESP8266 you should then open
+open webrepl.html in your browser and click the "Connect" button (if
+you are connecting via a router then you may need to change the IP address,
+by default the IP address is correct when connected to the ESP8266's access
+point). If the connection succeeds then you should see a welcome message.
+
+On the first connection you need to set a password. Make sure that the
+terminal widget is selected by clicking on it, and then type it your password
+twice (they should match each other). Then ESP8266 will then reboot with
+the password applied (the WiFi will go down but come back up again).
+
+You should then click the "Connect" button again, and enter your password
+to connect. If you type in the correct password you should get a prompt
+looking like ``>>>``. You can now start typing Python commands!
+
+Using the REPL
+--------------
+
+Once you have a prompt you can start experimenting! Anything you type at the
+prompt will be executed after you press the Enter key. MicroPython will run
+the code that you enter and print the result (if there is one). If there is an
+error with the text that you enter then an error message is printed.
+
+Try typing the following at the prompt::
+
+ >>> print('hello esp8266!')
+ hello esp8266!
+
+Note that you shouldn't type the ``>>>`` arrows, they are there to indicate that
+you should type the text after it at the prompt. And then the line following is
+what the device should respond with. In the end, once you have entered the text
+``print("hello esp8266!")`` and pressed the Enter key, the output on your screen
+should look exactly like it does above.
+
+If you already know some python you can now try some basic commands here. For
+example::
+
+ >>> 1 + 2
+ 3
+ >>> 1 / 2
+ 0.5
+ >>> 12**34
+ 4922235242952026704037113243122008064
+
+If your board has an LED attached to GPIO2 (the ESP-12 modules do) then you can
+turn it on and off using the following code::
+
+ >>> import machine
+ >>> pin = machine.Pin(2, machine.Pin.OUT)
+ >>> pin.high()
+ >>> pin.low()
+
+Note that ``high`` might turn the LED off and ``low`` might turn it on (or vice
+versa), depending on how the LED is wired on your board.
+
+Line editing
+~~~~~~~~~~~~
+
+You can edit the current line that you are entering using the left and right
+arrow keys to move the cursor, as well as the delete and backspace keys. Also,
+pressing Home or ctrl-A moves the cursor to the start of the line, and pressing
+End or ctrl-E moves to the end of the line.
+
+Input history
+~~~~~~~~~~~~~
+
+The REPL remembers a certain number of previous lines of text that you entered
+(up to 8 on the ESP8266). To recall previous lines use the up and down arrow
+keys.
+
+Tab completion
+~~~~~~~~~~~~~~
+
+Pressing the Tab key will do an auto-completion of the current word that you are
+entering. This can be very useful to find out functions and methods that a
+module or object has. Try it out by typing "ma" and then pressing Tab. It
+should complete to "machine" (assuming you imported machine in the above
+example). Then type "." and press Tab again to see a list of all the functions
+that the machine module has.
+
+Line continuation and auto-indent
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Certain things that you type will need "continuing", that is, will need more
+lines of text to make a proper Python statement. In this case the prompt will
+change to ``...`` and the cursor will auto-indent the correct amount so you can
+start typing the next line straight away. Try this by defining the following
+function::
+
+ >>> def toggle(p):
+ ... p.value(not p.value())
+ ...
+ ...
+ ...
+ >>>
+
+In the above, you needed to press the Enter key three times in a row to finish
+the compound statement (that's the three lines with just dots on them). The
+other way to finish a compound statement is to press backspace to get to the
+start of the line, then press the Enter key. (If you did something wrong and
+want to escape the continuation mode then press ctrl-C; all lines will be
+ignored.)
+
+The function you just defined allows you to toggle a pin. The pin object you
+created earlier should still exist (recreate it if it doesn't) and you can
+toggle the LED using::
+
+ >>> toggle(pin)
+
+Let's now toggle the LED in a loop (if you don't have an LED then you can just
+print some text instead of calling toggle, to see the effect)::
+
+ >>> import time
+ >>> while True:
+ ... toggle(pin)
+ ... time.sleep_ms(500)
+ ...
+ ...
+ ...
+ >>>
+
+This will toggle the LED at 1Hz (half a second on, half a second off). To stop
+the toggling press ctrl-C, which will raise a KeyboardInterrupt exception and
+break out of the loop.
+
+The time module provides some useful functions for making delays and doing
+timing. Use tab completion to find out what they are and play around with them!
+
+Paste mode
+~~~~~~~~~~
+
+Pressing ctrl-E will enter a special paste mode. This allows you to copy and
+paste a chunk of text into the REPL. If you press ctrl-E you will see the
+paste-mode prompt::
+
+ paste mode; Ctrl-C to cancel, Ctrl-D to finish
+ ===
+
+You can then paste (or type) your text in. Note that none of the special keys
+or commands work in paste mode (eg Tab or backspace), they are just accepted
+as-is. Press ctrl-D to finish entering the text and execute it.
+
+Other control commands
+~~~~~~~~~~~~~~~~~~~~~~
+
+There are four other control commands:
+
+* Ctrl-A on a blank line will enter raw REPL mode. This is like a permanent
+ paste mode, except that characters are not echoed back.
+
+* Ctrl-B on a blank like goes to normal REPL mode.
+
+* Ctrl-C cancels any input, or interrupts the currently running code.
+
+* Ctrl-D on a blank line will do a soft reset.
+
+Note that ctrl-A and ctrl-D do not work with WebREPL.