2018-09-27 08:27:57 +01:00
|
|
|
.. _esp8266_quickref:
|
2016-03-08 23:06:15 +00:00
|
|
|
|
|
|
|
Quick reference for the ESP8266
|
|
|
|
===============================
|
|
|
|
|
2016-06-01 21:11:49 +01:00
|
|
|
.. image:: img/adafruit_products_pinoutstop.jpg
|
2016-03-08 23:06:15 +00:00
|
|
|
:alt: Adafruit Feather HUZZAH board
|
|
|
|
:width: 640px
|
|
|
|
|
|
|
|
The Adafruit Feather HUZZAH board (image attribution: Adafruit).
|
|
|
|
|
2018-09-27 08:27:57 +01:00
|
|
|
Below is a quick reference for ESP8266-based boards. If it is your first time
|
|
|
|
working with this board please consider reading the following sections first:
|
|
|
|
|
|
|
|
.. toctree::
|
|
|
|
:maxdepth: 1
|
|
|
|
|
|
|
|
general.rst
|
|
|
|
tutorial/index.rst
|
|
|
|
|
2016-08-07 15:46:27 +01:00
|
|
|
Installing MicroPython
|
|
|
|
----------------------
|
|
|
|
|
|
|
|
See the corresponding section of tutorial: :ref:`intro`. It also includes
|
|
|
|
a troubleshooting subsection.
|
|
|
|
|
2016-03-08 23:06:15 +00:00
|
|
|
General board control
|
|
|
|
---------------------
|
|
|
|
|
2016-03-09 13:01:32 +00:00
|
|
|
The MicroPython REPL is on UART0 (GPIO1=TX, GPIO3=RX) at baudrate 115200.
|
2016-03-08 23:06:15 +00:00
|
|
|
Tab-completion is useful to find out what methods an object has.
|
|
|
|
Paste mode (ctrl-E) is useful to paste a large slab of Python code into
|
|
|
|
the REPL.
|
|
|
|
|
2016-08-29 08:40:36 +01:00
|
|
|
The :mod:`machine` module::
|
2016-03-08 23:06:15 +00:00
|
|
|
|
|
|
|
import machine
|
|
|
|
|
|
|
|
machine.freq() # get the current frequency of the CPU
|
|
|
|
machine.freq(160000000) # set the CPU frequency to 160 MHz
|
|
|
|
|
2016-08-29 08:40:36 +01:00
|
|
|
The :mod:`esp` module::
|
2016-03-08 23:06:15 +00:00
|
|
|
|
|
|
|
import esp
|
|
|
|
|
|
|
|
esp.osdebug(None) # turn off vendor O/S debugging messages
|
|
|
|
esp.osdebug(0) # redirect vendor O/S debugging messages to UART(0)
|
|
|
|
|
|
|
|
Networking
|
|
|
|
----------
|
|
|
|
|
2016-08-29 08:40:36 +01:00
|
|
|
The :mod:`network` module::
|
2016-03-08 23:06:15 +00:00
|
|
|
|
|
|
|
import network
|
|
|
|
|
|
|
|
wlan = network.WLAN(network.STA_IF) # create station interface
|
|
|
|
wlan.active(True) # activate the interface
|
|
|
|
wlan.scan() # scan for access points
|
|
|
|
wlan.isconnected() # check if the station is connected to an AP
|
|
|
|
wlan.connect('essid', 'password') # connect to an AP
|
2016-05-09 23:31:57 +01:00
|
|
|
wlan.config('mac') # get the interface's MAC adddress
|
2016-03-08 23:06:15 +00:00
|
|
|
wlan.ifconfig() # get the interface's IP/netmask/gw/DNS addresses
|
|
|
|
|
|
|
|
ap = network.WLAN(network.AP_IF) # create access-point interface
|
|
|
|
ap.active(True) # activate the interface
|
|
|
|
ap.config(essid='ESP-AP') # set the ESSID of the access point
|
|
|
|
|
|
|
|
A useful function for connecting to your local WiFi network is::
|
|
|
|
|
|
|
|
def do_connect():
|
|
|
|
import network
|
2016-03-09 13:01:32 +00:00
|
|
|
wlan = network.WLAN(network.STA_IF)
|
2016-03-08 23:06:15 +00:00
|
|
|
wlan.active(True)
|
|
|
|
if not wlan.isconnected():
|
|
|
|
print('connecting to network...')
|
2016-03-09 13:01:32 +00:00
|
|
|
wlan.connect('essid', 'password')
|
|
|
|
while not wlan.isconnected():
|
|
|
|
pass
|
|
|
|
print('network config:', wlan.ifconfig())
|
2016-03-08 23:06:15 +00:00
|
|
|
|
2016-08-29 08:40:36 +01:00
|
|
|
Once the network is established the :mod:`socket <usocket>` module can be used
|
2016-03-08 23:06:15 +00:00
|
|
|
to create and use TCP/UDP sockets as usual.
|
|
|
|
|
|
|
|
Delay and timing
|
|
|
|
----------------
|
|
|
|
|
2016-08-29 08:40:36 +01:00
|
|
|
Use the :mod:`time <utime>` module::
|
2016-03-08 23:06:15 +00:00
|
|
|
|
|
|
|
import time
|
|
|
|
|
|
|
|
time.sleep(1) # sleep for 1 second
|
|
|
|
time.sleep_ms(500) # sleep for 500 milliseconds
|
|
|
|
time.sleep_us(10) # sleep for 10 microseconds
|
|
|
|
start = time.ticks_ms() # get millisecond counter
|
2016-11-07 05:47:16 +00:00
|
|
|
delta = time.ticks_diff(time.ticks_ms(), start) # compute time difference
|
2016-03-08 23:06:15 +00:00
|
|
|
|
|
|
|
Timers
|
|
|
|
------
|
|
|
|
|
2017-04-18 06:28:18 +01:00
|
|
|
Virtual (RTOS-based) timers are supported. Use the :ref:`machine.Timer <machine.Timer>` class
|
2016-03-25 14:44:13 +00:00
|
|
|
with timer ID of -1::
|
2016-03-08 23:06:15 +00:00
|
|
|
|
|
|
|
from machine import Timer
|
|
|
|
|
2016-03-25 14:44:13 +00:00
|
|
|
tim = Timer(-1)
|
2016-03-09 11:02:38 +00:00
|
|
|
tim.init(period=5000, mode=Timer.ONE_SHOT, callback=lambda t:print(1))
|
|
|
|
tim.init(period=2000, mode=Timer.PERIODIC, callback=lambda t:print(2))
|
|
|
|
|
|
|
|
The period is in milliseconds.
|
2016-03-08 23:06:15 +00:00
|
|
|
|
|
|
|
Pins and GPIO
|
|
|
|
-------------
|
|
|
|
|
2017-04-18 06:28:18 +01:00
|
|
|
Use the :ref:`machine.Pin <machine.Pin>` class::
|
2016-03-08 23:06:15 +00:00
|
|
|
|
|
|
|
from machine import Pin
|
|
|
|
|
|
|
|
p0 = Pin(0, Pin.OUT) # create output pin on GPIO0
|
2017-05-31 20:57:11 +01:00
|
|
|
p0.on() # set pin to "on" (high) level
|
|
|
|
p0.off() # set pin to "off" (low) level
|
|
|
|
p0.value(1) # set pin to on/high
|
2016-03-08 23:06:15 +00:00
|
|
|
|
|
|
|
p2 = Pin(2, Pin.IN) # create input pin on GPIO2
|
|
|
|
print(p2.value()) # get value, 0 or 1
|
|
|
|
|
|
|
|
p4 = Pin(4, Pin.IN, Pin.PULL_UP) # enable internal pull-up resistor
|
|
|
|
p5 = Pin(5, Pin.OUT, value=1) # set pin high on creation
|
|
|
|
|
2016-04-05 14:29:52 +01:00
|
|
|
Available pins are: 0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 16, which correspond
|
|
|
|
to the actual GPIO pin numbers of ESP8266 chip. Note that many end-user
|
|
|
|
boards use their own adhoc pin numbering (marked e.g. D0, D1, ...). As
|
|
|
|
MicroPython supports different boards and modules, physical pin numbering
|
|
|
|
was chosen as the lowest common denominator. For mapping between board
|
|
|
|
logical pins and physical chip pins, consult your board documentation.
|
|
|
|
|
2016-03-08 23:06:15 +00:00
|
|
|
Note that Pin(1) and Pin(3) are REPL UART TX and RX respectively.
|
2016-03-25 14:48:15 +00:00
|
|
|
Also note that Pin(16) is a special pin (used for wakeup from deepsleep
|
|
|
|
mode) and may be not available for use with higher-level classes like
|
|
|
|
``Neopixel``.
|
2016-03-08 23:06:15 +00:00
|
|
|
|
|
|
|
PWM (pulse width modulation)
|
|
|
|
----------------------------
|
|
|
|
|
|
|
|
PWM can be enabled on all pins except Pin(16). There is a single frequency
|
|
|
|
for all channels, with range between 1 and 1000 (measured in Hz). The duty
|
|
|
|
cycle is between 0 and 1023 inclusive.
|
|
|
|
|
|
|
|
Use the ``machine.PWM`` class::
|
|
|
|
|
|
|
|
from machine import Pin, PWM
|
|
|
|
|
|
|
|
pwm0 = PWM(Pin(0)) # create PWM object from a pin
|
|
|
|
pwm0.freq() # get current frequency
|
|
|
|
pwm0.freq(1000) # set frequency
|
|
|
|
pwm0.duty() # get current duty cycle
|
|
|
|
pwm0.duty(200) # set duty cycle
|
|
|
|
pwm0.deinit() # turn off PWM on the pin
|
|
|
|
|
|
|
|
pwm2 = PWM(Pin(2), freq=500, duty=512) # create and configure in one go
|
|
|
|
|
|
|
|
ADC (analog to digital conversion)
|
|
|
|
----------------------------------
|
|
|
|
|
|
|
|
ADC is available on a dedicated pin.
|
|
|
|
Note that input voltages on the ADC pin must be between 0v and 1.0v.
|
|
|
|
|
2017-04-18 06:28:18 +01:00
|
|
|
Use the :ref:`machine.ADC <machine.ADC>` class::
|
2016-03-08 23:06:15 +00:00
|
|
|
|
|
|
|
from machine import ADC
|
|
|
|
|
|
|
|
adc = ADC(0) # create ADC object on ADC pin
|
|
|
|
adc.read() # read value, 0-1024
|
|
|
|
|
2016-09-04 21:31:05 +01:00
|
|
|
Software SPI bus
|
|
|
|
----------------
|
2016-03-08 23:06:15 +00:00
|
|
|
|
2016-09-04 19:13:55 +01:00
|
|
|
There are two SPI drivers. One is implemented in software (bit-banging)
|
2017-04-18 06:28:18 +01:00
|
|
|
and works on all pins, and is accessed via the :ref:`machine.SPI <machine.SPI>`
|
|
|
|
class::
|
2016-03-08 23:06:15 +00:00
|
|
|
|
|
|
|
from machine import Pin, SPI
|
|
|
|
|
|
|
|
# construct an SPI bus on the given pins
|
|
|
|
# polarity is the idle state of SCK
|
|
|
|
# phase=0 means sample on the first edge of SCK, phase=1 means the second
|
2016-08-27 18:07:14 +01:00
|
|
|
spi = SPI(-1, baudrate=100000, polarity=1, phase=0, sck=Pin(0), mosi=Pin(2), miso=Pin(4))
|
2016-03-08 23:06:15 +00:00
|
|
|
|
|
|
|
spi.init(baudrate=200000) # set the baudrate
|
|
|
|
|
|
|
|
spi.read(10) # read 10 bytes on MISO
|
2019-02-13 01:29:01 +00:00
|
|
|
spi.read(10, 0xff) # read 10 bytes while outputting 0xff on MOSI
|
2016-03-08 23:06:15 +00:00
|
|
|
|
|
|
|
buf = bytearray(50) # create a buffer
|
|
|
|
spi.readinto(buf) # read into the given buffer (reads 50 bytes in this case)
|
|
|
|
spi.readinto(buf, 0xff) # read into the given buffer and output 0xff on MOSI
|
|
|
|
|
|
|
|
spi.write(b'12345') # write 5 bytes on MOSI
|
|
|
|
|
|
|
|
buf = bytearray(4) # create a buffer
|
|
|
|
spi.write_readinto(b'1234', buf) # write to MOSI and read from MISO into the buffer
|
|
|
|
spi.write_readinto(buf, buf) # write buf to MOSI and read MISO back into buf
|
|
|
|
|
2016-06-07 20:40:56 +01:00
|
|
|
|
2016-09-04 21:31:05 +01:00
|
|
|
Hardware SPI bus
|
|
|
|
----------------
|
2016-06-07 20:40:56 +01:00
|
|
|
|
|
|
|
The hardware SPI is faster (up to 80Mhz), but only works on following pins:
|
2016-09-04 19:13:55 +01:00
|
|
|
``MISO`` is GPIO12, ``MOSI`` is GPIO13, and ``SCK`` is GPIO14. It has the same
|
2016-09-04 21:31:05 +01:00
|
|
|
methods as the bitbanging SPI class above, except for the pin parameters for the
|
|
|
|
constructor and init (as those are fixed)::
|
2016-06-07 20:40:56 +01:00
|
|
|
|
2016-08-27 18:07:14 +01:00
|
|
|
from machine import Pin, SPI
|
2016-06-07 20:40:56 +01:00
|
|
|
|
2016-09-04 19:13:55 +01:00
|
|
|
hspi = SPI(1, baudrate=80000000, polarity=0, phase=0)
|
2016-06-07 20:40:56 +01:00
|
|
|
|
2016-09-04 21:31:05 +01:00
|
|
|
(``SPI(0)`` is used for FlashROM and not available to users.)
|
2016-06-07 20:40:56 +01:00
|
|
|
|
2016-03-08 23:06:15 +00:00
|
|
|
I2C bus
|
|
|
|
-------
|
|
|
|
|
2017-04-18 06:28:18 +01:00
|
|
|
The I2C driver is implemented in software and works on all pins,
|
|
|
|
and is accessed via the :ref:`machine.I2C <machine.I2C>` class::
|
2016-03-08 23:06:15 +00:00
|
|
|
|
|
|
|
from machine import Pin, I2C
|
|
|
|
|
|
|
|
# construct an I2C bus
|
2016-03-09 11:02:38 +00:00
|
|
|
i2c = I2C(scl=Pin(5), sda=Pin(4), freq=100000)
|
2016-03-08 23:06:15 +00:00
|
|
|
|
2016-03-16 13:37:39 +00:00
|
|
|
i2c.readfrom(0x3a, 4) # read 4 bytes from slave device with address 0x3a
|
2016-03-08 23:06:15 +00:00
|
|
|
i2c.writeto(0x3a, '12') # write '12' to slave device with address 0x3a
|
|
|
|
|
|
|
|
buf = bytearray(10) # create a buffer with 10 bytes
|
|
|
|
i2c.writeto(0x3a, buf) # write the given buffer to the slave
|
|
|
|
|
2017-10-05 15:48:43 +01:00
|
|
|
Real time clock (RTC)
|
|
|
|
---------------------
|
|
|
|
|
|
|
|
See :ref:`machine.RTC <machine.RTC>` ::
|
|
|
|
|
|
|
|
from machine import RTC
|
|
|
|
|
|
|
|
rtc = RTC()
|
|
|
|
rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # set a specific date and time
|
|
|
|
rtc.datetime() # get date and time
|
|
|
|
|
2019-02-12 16:20:23 +00:00
|
|
|
# synchronize with ntp
|
|
|
|
# need to be connected to wifi
|
|
|
|
import ntptime
|
|
|
|
ntptime.settime() # set the rtc datetime from the remote server
|
|
|
|
rtc.datetime() # get the date and time in UTC
|
|
|
|
|
2019-12-14 15:56:14 +00:00
|
|
|
.. note:: Not all methods are implemented: `RTC.now()`, `RTC.irq(handler=*) <RTC.irq>`
|
|
|
|
(using a custom handler), `RTC.init()` and `RTC.deinit()` are
|
|
|
|
currently not supported.
|
|
|
|
|
2016-04-21 12:01:50 +01:00
|
|
|
Deep-sleep mode
|
|
|
|
---------------
|
|
|
|
|
|
|
|
Connect GPIO16 to the reset pin (RST on HUZZAH). Then the following code
|
|
|
|
can be used to sleep, wake and check the reset cause::
|
|
|
|
|
|
|
|
import machine
|
|
|
|
|
|
|
|
# configure RTC.ALARM0 to be able to wake the device
|
|
|
|
rtc = machine.RTC()
|
|
|
|
rtc.irq(trigger=rtc.ALARM0, wake=machine.DEEPSLEEP)
|
|
|
|
|
|
|
|
# check if the device woke from a deep sleep
|
|
|
|
if machine.reset_cause() == machine.DEEPSLEEP_RESET:
|
|
|
|
print('woke from a deep sleep')
|
|
|
|
|
|
|
|
# set RTC.ALARM0 to fire after 10 seconds (waking the device)
|
|
|
|
rtc.alarm(rtc.ALARM0, 10000)
|
|
|
|
|
|
|
|
# put the device to sleep
|
|
|
|
machine.deepsleep()
|
|
|
|
|
2016-03-08 23:06:15 +00:00
|
|
|
OneWire driver
|
|
|
|
--------------
|
|
|
|
|
|
|
|
The OneWire driver is implemented in software and works on all pins::
|
|
|
|
|
|
|
|
from machine import Pin
|
|
|
|
import onewire
|
|
|
|
|
|
|
|
ow = onewire.OneWire(Pin(12)) # create a OneWire bus on GPIO12
|
|
|
|
ow.scan() # return a list of devices on the bus
|
|
|
|
ow.reset() # reset the bus
|
2016-04-28 14:31:37 +01:00
|
|
|
ow.readbyte() # read a byte
|
|
|
|
ow.writebyte(0x12) # write a byte on the bus
|
|
|
|
ow.write('123') # write bytes on the bus
|
2016-03-08 23:06:15 +00:00
|
|
|
ow.select_rom(b'12345678') # select a specific device by its ROM code
|
|
|
|
|
2016-08-29 03:52:50 +01:00
|
|
|
There is a specific driver for DS18S20 and DS18B20 devices::
|
2016-03-08 23:06:15 +00:00
|
|
|
|
2016-08-29 03:52:50 +01:00
|
|
|
import time, ds18x20
|
|
|
|
ds = ds18x20.DS18X20(ow)
|
2016-03-08 23:06:15 +00:00
|
|
|
roms = ds.scan()
|
2016-04-28 14:31:37 +01:00
|
|
|
ds.convert_temp()
|
2016-03-08 23:06:15 +00:00
|
|
|
time.sleep_ms(750)
|
|
|
|
for rom in roms:
|
2016-04-28 14:31:37 +01:00
|
|
|
print(ds.read_temp(rom))
|
2016-03-08 23:06:15 +00:00
|
|
|
|
2016-04-28 14:31:37 +01:00
|
|
|
Be sure to put a 4.7k pull-up resistor on the data line. Note that
|
|
|
|
the ``convert_temp()`` method must be called each time you want to
|
|
|
|
sample the temperature.
|
2016-03-08 23:06:15 +00:00
|
|
|
|
|
|
|
NeoPixel driver
|
|
|
|
---------------
|
|
|
|
|
|
|
|
Use the ``neopixel`` module::
|
|
|
|
|
|
|
|
from machine import Pin
|
2016-03-16 13:37:39 +00:00
|
|
|
from neopixel import NeoPixel
|
2016-03-08 23:06:15 +00:00
|
|
|
|
|
|
|
pin = Pin(0, Pin.OUT) # set GPIO0 to output to drive NeoPixels
|
|
|
|
np = NeoPixel(pin, 8) # create NeoPixel driver on GPIO0 for 8 pixels
|
|
|
|
np[0] = (255, 255, 255) # set the first pixel to white
|
|
|
|
np.write() # write data to all pixels
|
|
|
|
r, g, b = np[0] # get first pixel colour
|
|
|
|
|
|
|
|
For low-level driving of a NeoPixel::
|
|
|
|
|
|
|
|
import esp
|
|
|
|
esp.neopixel_write(pin, grb_buf, is800khz)
|
2016-05-01 09:41:25 +01:00
|
|
|
|
2016-03-28 00:58:14 +01:00
|
|
|
APA102 driver
|
|
|
|
-------------
|
|
|
|
|
|
|
|
Use the ``apa102`` module::
|
|
|
|
|
|
|
|
from machine import Pin
|
|
|
|
from apa102 import APA102
|
|
|
|
|
|
|
|
clock = Pin(14, Pin.OUT) # set GPIO14 to output to drive the clock
|
|
|
|
data = Pin(13, Pin.OUT) # set GPIO13 to output to drive the data
|
|
|
|
apa = APA102(clock, data, 8) # create APA102 driver on the clock and the data pin for 8 pixels
|
|
|
|
apa[0] = (255, 255, 255, 31) # set the first pixel to white with a maximum brightness of 31
|
|
|
|
apa.write() # write data to all pixels
|
|
|
|
r, g, b, brightness = apa[0] # get first pixel colour
|
|
|
|
|
|
|
|
For low-level driving of an APA102::
|
|
|
|
|
|
|
|
import esp
|
|
|
|
esp.apa102_write(clock_pin, data_pin, rgbi_buf)
|
|
|
|
|
2016-07-28 05:24:21 +01:00
|
|
|
DHT driver
|
|
|
|
----------
|
|
|
|
|
|
|
|
The DHT driver is implemented in software and works on all pins::
|
|
|
|
|
|
|
|
import dht
|
|
|
|
import machine
|
|
|
|
|
|
|
|
d = dht.DHT11(machine.Pin(4))
|
|
|
|
d.measure()
|
|
|
|
d.temperature() # eg. 23 (°C)
|
|
|
|
d.humidity() # eg. 41 (% RH)
|
|
|
|
|
|
|
|
d = dht.DHT22(machine.Pin(4))
|
|
|
|
d.measure()
|
|
|
|
d.temperature() # eg. 23.6 (°C)
|
|
|
|
d.humidity() # eg. 41.3 (% RH)
|
|
|
|
|
2016-05-01 09:41:25 +01:00
|
|
|
WebREPL (web browser interactive prompt)
|
|
|
|
----------------------------------------
|
|
|
|
|
|
|
|
WebREPL (REPL over WebSockets, accessible via a web browser) is an
|
|
|
|
experimental feature available in ESP8266 port. Download web client
|
2016-06-02 18:11:40 +01:00
|
|
|
from https://github.com/micropython/webrepl (hosted version available
|
2016-11-06 07:02:33 +00:00
|
|
|
at http://micropython.org/webrepl), and configure it by executing::
|
2016-05-01 09:41:25 +01:00
|
|
|
|
2016-11-06 07:02:33 +00:00
|
|
|
import webrepl_setup
|
2016-05-01 09:41:25 +01:00
|
|
|
|
2016-11-06 07:02:33 +00:00
|
|
|
and following on-screen instructions. After reboot, it will be available
|
|
|
|
for connection. If you disabled automatic start-up on boot, you may
|
|
|
|
run configured daemon on demand using::
|
2016-05-01 09:41:25 +01:00
|
|
|
|
2016-11-06 07:02:33 +00:00
|
|
|
import webrepl
|
|
|
|
webrepl.start()
|
2016-05-01 09:41:25 +01:00
|
|
|
|
|
|
|
The supported way to use WebREPL is by connecting to ESP8266 access point,
|
|
|
|
but the daemon is also started on STA interface if it is active, so if your
|
2016-06-02 18:11:40 +01:00
|
|
|
router is set up and works correctly, you may also use WebREPL while connected
|
|
|
|
to your normal Internet access point (use the ESP8266 AP connection method
|
|
|
|
if you face any issues).
|
2016-05-01 09:41:25 +01:00
|
|
|
|
2016-11-06 07:02:33 +00:00
|
|
|
Besides terminal/command prompt access, WebREPL also has provision for file
|
|
|
|
transfer (both upload and download). Web client has buttons for the
|
|
|
|
corresponding functions, or you can use command-line client ``webrepl_cli.py``
|
|
|
|
from the repository above.
|
2016-06-02 18:11:40 +01:00
|
|
|
|
2016-11-06 07:02:33 +00:00
|
|
|
See the MicroPython forum for other community-supported alternatives
|
|
|
|
to transfer files to ESP8266.
|