MicroPython:Платы/ESP8266/Краткий справочник по ESP8266

Материал из Онлайн справочника
Перейти к навигации Перейти к поиску

Перевод: Максим Кузьмин (Cubewriter) Контакты:</br>* Skype: cubewriter</br>* E-mail: cubewriter@gmail.com</br>* Максим Кузьмин на freelance.ru
Проверка/Оформление/Редактирование: Мякишев Е.А.


Краткий справочник по ESP8266[1]

Adafruit products pinoutstop.jpg

Плата Adafruit Feather HUZZAH (источник изображения – Adafruit).

Материал ниже – краткий справочник по платам на базе ESP8266. Если вы впервые работаете с такой

платой, советуем сначала прочесть вот эти разделы:

Установка MicroPython

Читайте соответствующий раздел «Подготовка к работе с MicroPython на ESP8266». Там также есть подраздел «Решение проблем с установкой» (1.7).

Общее управление платой

REPL MicroPython работает на порте UART0 (GPIO1=TX, GPIO3=RX) на скорости 115200 бод. Чтобы узнать, какие методы есть в объекте, используйте автодополнение с помощью клавиши  Tab ⇆ . Чтобы вставить в REPL большой кусок Python-кода, используйте режим вставки ( Ctrl + E ).

Модуль machine:

1 import machine
2 
3 machine.freq()          # узнать текущую частоту CPU
4 machine.freq(160000000) # задать частоту CPU на 160 МГц

Модуль esp:

1 import esp
2 
3 esp.osdebug(None)       # отключить отладочные сообщения ОС
4 esp.osdebug(0)          # перенаправить отладочные сообщения ОС на 
5                           UART(0)

Сеть

Модуль network:

 1 import network
 2 
 3 wlan = network.WLAN(network.STA_IF) # создать интерфейс для работы
 4                                     # в режиме станции
 5 wlan.active(True)       # активировать интерфейс
 6 wlan.scan()             # сканировать точки доступа
 7 wlan.isconnected()      # проверить, подключена ли станция 
 8                         # к точке доступа
 9 wlan.connect('essid', 'пароль') # подключиться к точке доступа
10 wlan.config('mac')      # прочесть MAC-адрес интерфейса
11 wlan.ifconfig()         # прочесть IP, маску подсети
12                         # сетевой шлюз и DNS-сервер интерфейса
13 
14 ap = network.WLAN(network.AP_IF) # создать интерфейс для работы
15                                  # в режиме точки доступа
16 ap.active(True)         # активировать интерфейс
17 ap.config(essid='ESP-AP') # задать ESSID точки доступа

Полезная функция для подключения к вашей локальной WiFi-сети:

 1 def do_connect():
 2     import network
 3     wlan = network.WLAN(network.STA_IF)
 4     wlan.active(True)
 5     if not wlan.isconnected():
 6         print('подключение к сети...')
 7         wlan.connect('essid', 'пароль')
 8         while not wlan.isconnected():
 9             pass
10     print('настройки сети:', wlan.ifconfig())

Выполнив подключение к сети, вы сможете использовать модуль socket, позволяющий в обычном режиме использовать TCP/UDP-сокеты.

Задержки и синхронизация

Используйте модуль time.

1 import time
2 
3 time.sleep(1)           # войти в режим сна на 1 секунду
4 time.sleep_ms(500)      # войти в режим сна на 500 миллисекунд
5 time.sleep_us(10)       # войти в режим сна на 10 микросекунд
6 start = time.ticks_ms() # прочесть показания счетчика миллисекунд
7 delta = time.ticks_diff(time.ticks_ms(), start) # рассчитать 
8                                                 # разницу времени

Таймеры

MicroPython поддерживает использование виртуальных RTOS-таймеров. Используйте для этого класс machine.Timer с ID таймера «-1».

1 from machine import Timer
2 
3 tim = Timer(-1)
4 tim.init(period=5000, mode=Timer.ONE_SHOT, callback=lambda t:print(1))
5 tim.init(period=2000, mode=Timer.PERIODIC, callback=lambda t:print(2))

Значение в переменной period рассчитывается в миллисекундах.

Контакты и GPIO

Используйте класс machine.Pin.

 1 from machine import Pin
 2 
 3 p0 = Pin(0, Pin.OUT)    # создать выходной контакт на GPIO0
 4 p0.on()                 # задать контакту значение «вкл» или «1»
 5 p0.off()                # задать контакту значение «выкл» или «0»
 6 p0.value(1)             # задать контакту значение «вкл» или «1»
 7 
 8 p2 = Pin(2, Pin.IN)     # создать входной контакт на GPIO2
 9 print(p2.value())       # прочесть значение («0» или «1»)
10 
11 p4 = Pin(4, Pin.IN, Pin.PULL_UP) # включить встроенный
12                                  # подтягивающий резистор
13 p5 = Pin(5, Pin.OUT, value=1) # создать выходной контакт 
14                               # и присвоить ему значение «1»

Для использования доступны контакты 0, 1, 2, 3, 4, 5, 12, 13, 14, 15, 16 – все они соответствуют номерам GPIO-контактов на чипе ESP8266. Помните, что у многих плат имеется собственная нумерация контактов (с обозначениями вроде D0, D1 и т.д.). Поскольку MicroPython поддерживает разные платы и модули, эта нумерация, привязанная к физическим контактам чипа, была выбрана в качестве наименьшего общего знаменателя. Поэтому, чтобы узнать точное соответствие между физическими и логическими контактами своей модели, проконсультируйтесь у производителя платы.

Помните, что контакты 1 и 3 – это, соответственно, передающий (TX) и приемный (RX) UART-контакты для REPL. Также помните, что 16-ый контакт – это специальный контакт (используемый для выхода из режима глубокого сна), который может быть не доступен для использования высокоуровневыми классами вроде Neopixel.

UART (последовательная шина)

См. machine.UART.

1 from machine import UART
2 uart = UART(0, baudrate=9600)
3 uart.write('привет')
4 uart.read(5) # прочесть до пяти байтов

MicroPython поддерживает использование двух UART-портов. UART0 находится на контактах 1 (TX) и 3 (RX). Это порт, работающий в обоих направлениях, и по умолчанию он используется для REPL. Порт UART1 работает на контактах 2 (TX) и 8 (RX), но контакт 8 также используется для подключения к чипу флеш-памяти, поэтому у UART1 только передающий (TX) контакт.

Когда UART0 подключен к REPL, все символы, приходящие на этот порт, идут прямиком в stdin, поэтому uart.read() всегда будет возвращать None. Поэтому, если вам нужно прочесть символы из UART0, но он уже используется для REPL, используйте sys.stdin.read() (или отключите REPL от UART0, прочтите данные, а потом снова подключите). Когда REPL отключен от UART0, его можно использовать и для других целей.

Если при запуске REPL (будь то мягкая или полная перезагрузка) в dupterm-слотах нет объектов, UART0 будет подключен по умолчанию. Без UART0 и REPL единственный способ восстановить плату – это полностью стереть и перезаписать прошивку (что установит стандартный «boot.py», в котором REPL будет уже подключен).

Чтобы отключить REPL от UART0, используйте:

1 import uos
2 uos.dupterm(None, 1)

По умолчанию REPL подключен к UART0. Если вы отключили его, то подключить обратно можно вот так:

1 import uos, machine
2 uart = machine.UART(0, 115200)
3 uos.dupterm(uart, 1)

ШИМ (широтно-импульсная модуляция)

ШИМ можно включить на всех контактах, кроме 16-го, но на всех этих каналах можно передавать лишь одну частоту в диапазоне между 1 и 1000 Гц. Коэффициент заполнения – между 0 и 1023 включительно.

Используйте класс machine.PWM:

 1 from machine import Pin, PWM
 2 
 3 pwm0 = PWM(Pin(0))      # создать ШИМ-объект на контакте 0
 4 pwm0.freq()             # прочесть текущую частоту
 5 pwm0.freq(1000)         # задать частоту
 6 pwm0.duty()             # прочесть текущий коэффициент заполнения
 7 pwm0.duty(200)          # задать коэффициент заполнения
 8 pwm0.deinit()           # выключить ШИМ на контакте
 9 
10 pwm2 = PWM(Pin(2), freq=500, duty=512) # создать ШИМ-объект
11                                        # и сразу же настроить его

АЦП (аналогово-цифровое преобразование)

Для АЦП используется специальный контакт. Помните, что входное напряжение на АЦП должно быть в диапазоне между 0 и 1 вольтом.

Используйте класс machine.ADC:

1 from machine import ADC
2 
3 adc = ADC(0)            # создать АЦП-объект на АЦП-контакте
4 adc.read()              # прочесть значение («0-1024»)

Программная шина SPI

В MicroPython для ESP8266 реализовано два SPI-драйвера. Один реализован программно (с помощью технологии «bit-banging»), работает на всех контактах и доступен через класс machine.SPI.

 1 from machine import Pin, SPI
 2 
 3 # создаем SPI-шину на заданных контактах;
 4 # значение «polarity» отвечает за то, 
 5 # находится ли линия SCK в состоянии простоя или нет; 
 6 # «phase=0» значит, что выборка данных происходит
 7 # на переднем фронте тактового сигнала, а «phase=1» - на заднем.
 8 spi = SPI(-1, baudrate=100000, polarity=1, phase=0, sck=Pin(0), mosi=Pin(2), miso=Pin(4))
 9 
10 spi.init(baudrate=200000) # задать скорость коммуникации в бодах
11 
12 spi.read(10)            # прочесть 10 байт на MISO-линии
13 spi.read(10, 0xff)      # прочесть 10 байт, попутно передавая
14                         # на MOSI-линию значение «0xff»
15 
16 buf = bytearray(50)     # создать буфер 
17 spi.readinto(buf)       # сохранить считанные данные в заданный буфер
18                         # (в данном случае его размер будет 50 байт)
19 spi.readinto(buf, 0xff) # сохранить считанные данные в заданный буфер
20                         # и передать на MOSI-линию значение «0xff» 
21 
22 spi.write(b'12345')     # записать 5 байт на MOSI-линию
23 
24 buf = bytearray(4)      # создать буфер
25 spi.write_readinto(b'1234', buf) # записать на MOSI-линию
26                                  # и прочесть из MISO-линии в буфер
27 spi.write_readinto(buf, buf) # записать данные буфера в MOSI-линию
28                              # и сохранить данные из MISO в буфер

Аппаратная шина SPI

Аппаратный SPI работает быстрее (до 80 МГц) программного, но только на следующих контактах: GPIO12 (MISO), GPIO13 (MOSI) и GPIO14 (SCK). У него те же методы, что и у программного SPI (см. раздел выше), кроме параметров контактов для конструктора и init() (т.к. они фиксированные):

1 from machine import Pin, SPI
2 
3 hspi = SPI(1, baudrate=80000000, polarity=0, phase=0)

SPI(0) используется для FlashROM и недоступен пользователям.

Шина I2C

Драйвер I2C реализован программно, работает на всех контактах и доступен через класс machine.I2C:

 1 from machine import Pin, I2C
 2 
 3 # создать шину I2C:
 4 i2c = I2C(scl=Pin(5), sda=Pin(4), freq=100000)
 5 
 6 i2c.readfrom(0x3a, 4)   # прочесть 4 байта с ведомого устройства
 7                         # с адресом «0x3a»
 8 i2c.writeto(0x3a, '12') # записать «12» на ведомое устройство
 9                         # с адресом «0x3a»
10 
11 buf = bytearray(10)     # создать буфер с 10 байтами
12 i2c.writeto(0x3a, buf)  # записать данные из заданного буфера
13                         # на ведомое устройство

Часы реального времени (RTC)

См. класс machine.RTC.

 1 from machine import RTC
 2 
 3 rtc = RTC()
 4 rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # задать дату и время
 5 rtc.datetime() # прочесть дату и время
 6 
 7 # синхронизация с NTP (нужно подключение к WiFi):
 8 import ntptime
 9 ntptime.settime() # задать RTC-данные о дате и времени
10                   # на основе данных дистанционного сервера
11 rtc.datetime()    # прочесть RTC-данные о дате и времени
12                   # в стандарте всемирного координированного времени

Примечание: В этом классе реализованы не все методы: RTC.now(), RTC.irq(handler=*)(в параметре можно задать пользовательскую функцию), RTC.init() и RTC.deinit() в данный момент не поддерживаются.

Режим глубокого сна

Код ниже можно использовать для входа в режим глубокого сна, пробуждения и проверки того, является ли причиной перезагрузки выход из режима глубокого сна. Но для этого контакт GPIO16 сначала нужно подключить к контакту сброса (на HUZZAH это «RST»):

 1 import machine
 2 
 3 # настроить RTC.ALARM0, чтобы устройство 
 4 # можно было вывести из режима глубокого сна:
 5 rtc = machine.RTC()
 6 rtc.irq(trigger=rtc.ALARM0, wake=machine.DEEPSLEEP)
 7 
 8 # проверить, является ли причиной перезагрузки
 9 # выход из режима глубокого сна:
10 if machine.reset_cause() == machine.DEEPSLEEP_RESET:
11     print('woke from a deep sleep')
12 
13 # настроить RTC.ALARM0 на запуск
14 # через 10 секунд (пробуждение устройства):
15 rtc.alarm(rtc.ALARM0, 10000)
16 
17 # перевести устройство в режим глубокого сна:
18 machine.deepsleep()

Шина OneWire

Драйвер OneWire реализована программно и работает на всех контактах:

 1 from machine import Pin
 2 import onewire
 3 
 4 ow = onewire.OneWire(Pin(12)) # создать шину OneWire на GPIO12
 5 ow.scan()               # вернуть список устройств,
 6                         # подключенных к шине
 7 ow.reset()              # сбросить шину
 8 ow.readbyte()           # прочесть байт
 9 ow.writebyte(0x12)      # записать байт на шину
10 ow.write('123')         # записать байты на шину
11 ow.select_rom(b'12345678') # выбрать устройство по его ROM-коду

Есть также специальный драйвер для устройств DS18S20 и DS18B20:

1 import time, ds18x20
2 ds = ds18x20.DS18X20(ow)
3 roms = ds.scan()
4 ds.convert_temp()
5 time.sleep_ms(750)
6 for rom in roms:
7     print(ds.read_temp(rom))

Убедитесь, что на линии данных включен подтягивающий резистор на 4.7 кОм. И помните, что при каждом считывании данных о температуре нужно вызывать метод convert_temp().

Драйвер для NeoPixel

Используйте модуль neopixel:

 1 from machine import Pin
 2 from neopixel import NeoPixel
 3 
 4 pin = Pin(0, Pin.OUT)   # перевести GPIO0 в режим вывода данных
 5                         # для управления устройствами NeoPixel
 6 np = NeoPixel(pin, 8)   # создать NeoPixel-драйвер
 7                         # на GPIO0 для 8 пикселей
 8 np[0] = (255, 255, 255) # сделать первый пиксель белым
 9 np.write()              # записать данные на все пиксели
10 r, g, b = np[0]         # прочесть цвет первого пикселя

Для низкоуровневого управления устройствами NeoPixel:

1 import esp
2 esp.neopixel_write(pin, grb_buf, is800khz)

Драйвер для APA102

Используйте модуль apa102:

 1 from machine import Pin
 2 from apa102 import APA102
 3 
 4 clock = Pin(14, Pin.OUT)     # перевести GPIO14 в режим вывода данных
 5                              # для управления тактовой частотой
 6 data = Pin(13, Pin.OUT)      # перевести GPIO13 в режим вывода данных 
 7                              # для управления данными
 8 apa = APA102(clock, data, 8) # создать драйвер APA102 на контактах
 9                              # для тактовой частоты и данных
10                              # для 8 пикселей 
11 apa[0] = (255, 255, 255, 31) # сделать первый пиксель белым
12                              # с максимальной яркостью «31»
13 apa.write()                  # записать данные на все пиксели 
14 r, g, b, brightness = apa[0] # задать цвет первого пикселя

Для низкоуровневого управления APA102:

1 import esp
2 esp.apa102_write(clock_pin, data_pin, rgbi_buf)

Драйвер для DHT-датчиков

DHT-драйвер реализован программно и работает на всех контактах:

 1 import dht
 2 import machine
 3 
 4 d = dht.DHT11(machine.Pin(4))
 5 d.measure()
 6 d.temperature() # например, 23 (градуса Цельсия)
 7 d.humidity()    # например, 41 (% относительной влажности)
 8 
 9 d = dht.DHT22(machine.Pin(4))
10 d.measure()
11 d.temperature() # например 23.6 (градуса Цельсия)
12 d.humidity()    # например, 41.3 (% относительной влажности)

WebREPL (интерактивная браузерная командная строка)

WebREPL (REPL, реализованная через WebSockets и доступная через браузер) – это экспериментальная функция порта MicroPython для ESP8266. Загрузите веб-клиент отсюда (или воспользуйтесь клиентом, уже развернутом на сервере сайта micropython.org), а затем настройте его, выполнив следующее…

import webrepl_setup

…а затем следуя инструкциям на экране. Подключиться к WebREPL можно будет после перезагрузки. Если у вас отключен автоматический запуск WebREPL при загрузке, вы всегда можете запустить демон WebREPL сами при помощи:

import webrepl
webrepl.start()

В MicroPython поддерживается WebREPL через подключение к точке доступа ESP8266, но если режим станции активен, демон WebREPL запустится и на нем, поэтому если ваш роутер настроен и исправно работает, вы можете использовать WebREPL, будучи подключенным к обычной точке доступа в интернет (если у вас возникли какие-то проблемы, используйте подключение к точке доступа ESP8266).

Помимо доступа к командной строке (терминалу), в WebREPL также есть функционал для загрузки (и отправки, и получения) файлов. В веб-клиенте для этих функций есть соответствующие кнопки, или же вы можете воспользоваться клиентом командной строки webrepl_cli.py из репозитория выше.

Также есть другие способы для отправки и получения файлов на ESP8266, созданные и поддерживаемые сообществом MicroPython. Ищите эти альтернативы на форуме MicroPython.

См.также

Внешние ссылки