Wprowadzenie do micropython na esp8266/esp8265¶
https://towardsdatascience.com/micropython-on-esp-using-jupyter-6f366ff5ed9
https://docs.micropython.org/en/latest/esp8266/tutorial/intro.html
Instalacja firmware micropython¶
Dokładny opis:¶
- https://docs.micropython.org/en/latest/esp8266/tutorial/intro.html
- http://www.wbudowane.pl/category/esp8266/
https://www.hackster.io/mjrobot/micropython-on-esp-using-jupyter-dfd1b3
Skrótowy opis:¶
- Należy zainstalować wybraną dystrybucję Python (polecam ANACONDA lub MINICONDA)
- Pobrać ostatnie firmware http://micropython.org/download#esp8266
- Uruchomić linię poleceń Python (np. Anaconda Prompt)
- pip install esptool
- esptool –port COM7 erase_flash
- esptool –port COM7 –baud 460800 write_flash –flash_size=detect 0
esp8266-20180511-v1.9.4.bin
- Dla różnych mikroprocesorów i płytek istotne są przede wszystkim dwa parametry “–flash_mode=” oraz “–flash_size=”
- Dla większości ESP8266 (np. WiFi Witty) “flash_mode” można pozostawić
domyślnie i podać tylko : –flash_size=detect
- Dla np. Wemos D1 mini lite (ESP8265): –flash_mode=dout
–flash_size=detect
- Dla ESP32 konieczna jest zmiana adresu z 0 na 0x1000
Korzystając z funkcji „magic” jądra micropython¶
In [1]:
%lsmagic
%capture [--quiet] [--QUIET] outputfilename
records output to a file
%comment
print this into output
%disconnect [--raw]
disconnects from web/serial connection
%esptool [--port PORT] {erase,esp32,esp8266} [binfile]
commands for flashing your esp-device
%fetchfile [--binary] [--print] [--quiet] [--QUIET]
sourcefilename [destinationfilename]
fetch and save a file from the device
%lsmagic
list magic commands
%mpy-cross [--set-exe SET_EXE] [pyfile]
cross-compile a .py file to a .mpy file
%readbytes
does serial.read_all()
%readbytes [--binary]
does serial.read_all()
%rebootdevice
reboots device
%sendtofile [--append] [--mkdir] [--binary] [--execute]
[--source [SOURCE]] [--quiet] [--QUIET]
[destinationfilename]
send cell contents or file/direcectory to the device
%serialconnect [--raw] [--port PORT] [--baud BAUD] [--verbose]
connects to a device over USB wire
%socketconnect [--raw] ipnumber portnumber
connects to a socket of a device over wifi
%suppressendcode
doesn't send x04 or wait to read after sending the contents of the cell
(assists for debugging using %writebytes and %readbytes)
%websocketconnect [--raw] [--password PASSWORD] [--verbose]
[websocketurl]
connects to the webREPL websocket of an ESP8266 over wifi
websocketurl defaults to ws://192.168.4.1:8266 but be sure to be connected
%writebytes [--binary] [--verbose] stringtosend
does serial.write() of the python quoted string given
%%writefile [--append] [--execute] destinationfilename
write contents of cell to a file
In [2]:
%esptool
usage: %esptool [--port PORT] {erase,esp32,esp8266} [binfile]
positional arguments:
{erase,esp32,esp8266}
binfile
optional arguments:
--port PORT
Please download the bin file from https://micropython.org/download/#
In [5]:
%esptool --port COM6 erase
Executing:
esptool --port COM6 erase_flash
esptool.py v2.5.1
Serial port COM6
Connecting....
[Press the PRG button now if required]
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
MAC: 5c:cf:7f:c1:7e:c8
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 8.6s
Hard resetting via RTS pin...
In [6]:
%esptool --port COM6 esp8266 esp8266-20180511-v1.9.4.bin
Executing:
esptool --port COM6 --baud 460800 write_flash --flash_size=detect -fm dio 0 esp8266-20180511-v1.9.4.bin
esptool.py v2.5.1
Serial port COM6
Connecting....
[Press the PRG button now if required]
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
MAC: 5c:cf:7f:c1:7e:c8
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Auto-detected Flash size: 4MB
Flash params set to 0x0240
Compressed 604872 bytes to 394893...
Wrote 604872 bytes (394893 compressed) at 0x00000000 in 9.2 seconds (effective 523.7 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...
Pierwsze połączenie¶
In [1]:
%serialconnect to --port=COM6 --baud=115200
Connecting to --port=COM6 --baud=115200
Ready.
In [2]:
help()
Welcome to MicroPython!
For online docs please visit http://docs.micropython.org/en/latest/esp8266/ .
For diagnostic information to include in bug reports execute 'import port_diag'.
Basic WiFi configuration:
import network
sta_if = network.WLAN(network.STA_IF); sta_if.active(True)
sta_if.scan() # Scan for available access points
sta_if.connect("<AP_name>", "<password>") # Connect to an AP
sta_if.isconnected() # Check for successful connection
# Change name/password of ESP8266's AP:
ap_if = network.WLAN(network.AP_IF)
ap_if.config(essid="<AP_NAME>", authmode=network.AUTH_WPA_WPA2_PSK, password="<password>")
Control commands:
CTRL-A -- on a blank line, enter raw REPL mode
CTRL-B -- on a blank line, enter normal REPL mode
CTRL-C -- interrupt a running program
CTRL-D -- on a blank line, do a soft reset of the board
CTRL-E -- on a blank line, enter paste mode
For further help on a specific object, type help(obj)
In [3]:
help('modules')
__main__ http_client_ssl sys urandom
_boot http_server time ure
_onewire http_server_ssl uasyncio/__init__ urequests
_webrepl inisetup uasyncio/core urllib/urequest
apa102 json ubinascii uselect
array lwip ucollections usocket
btree machine uctypes ussl
builtins math uerrno ustruct
dht micropython uhashlib utime
ds18x20 neopixel uheapq utimeq
errno network uio uzlib
esp ntptime ujson webrepl
example_pub_button onewire umqtt/robust webrepl_setup
example_sub_led os umqtt/simple websocket
flashbdev port_diag uos websocket_helper
framebuf select upip
gc socket upip_utarfile
http_client ssd1306 upysh
Plus any modules on the filesystem
Polaczenie WiFi¶
In [4]:
import network
In [5]:
sta_if = network.WLAN(network.STA_IF); sta_if.active(True)
#6 ets_task(4020f474, 28, 3fffa018, 10)
In [7]:
print(sta_if.scan()) # Scan for available access points
[(b'Redmi', b'x\x02\xf8\xf7\x0e\xe4', 1, -47, 0, 0), (b'AGH-Events', b'\x00#3,\x13\xe3', 1, -93, 0, 0), (b'AGH-WPA', b'\x00#3,\x13\xe1', 1, -91, 0, 0), (b'pud', b'\x00\x18\xe7\xf5\xcc\xdc', 1, -91, 4, 0), (b'AGH-Guest', b'TJ\x00\xc7/0', 6, -89, 0, 0), (b'eduroam', b'TJ\x00\xc7/2', 6, -91, 0, 0), (b'AGH-WPA', b'TJ\x00\xc7/1', 6, -89, 0, 0), (b'AGH-Events', b'TJ\x00\xc7/3', 6, -90, 0, 0), (b'KRiM_G_2G', b'\x18\xd6\xc7\xab\xf9y', 8, -88, 3, 0), (b'AGH-Guest', b'\x00#3,\x13\xe0', 1, -92, 0, 0), (b'eduroam', b'\x00#3,\x13\xe2', 1, -89, 0, 0)]
In [8]:
sta_if.connect("Redmi", "") # Connect to an AP
In [10]:
print(sta_if.isconnected()) # Check for successful connection
True
Polecenia sprzętowe¶
Częstotliwość procesora i czas¶
In [11]:
import machine
In [12]:
print(machine.freq()) # get the current frequency of the CPU
80000000
In [13]:
machine.freq(160000000) # set the CPU frequency to 160 MHz
In [14]:
print(machine.freq()) # get the current frequency of the CPU
160000000
In [15]:
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
time.sleep_us(1000)
delta = time.ticks_diff(time.ticks_ms(), start) # compute time difference
print(delta)
.1
Wejścia i wyjścia cyfrowe¶
In [17]:
from machine import Pin
pinR = Pin(15, Pin.OUT) # create output pin on GPIO0
In [19]:
pinR.on() # set pin to "off" (low) level
time.sleep(1)
pinR.off() # set pin to "on" (high) level
time.sleep(1)
pinR.value(1) # set pin to on/high
time.sleep(1)
pinR.value(0) # set pin to off/low
.
In [21]:
p4 = Pin(4, Pin.IN) # create input pin on GPIO4
print(p4.value()) # get value, 0 or 1
0
Wejście 1-Wire (ds18x20)¶
In [25]:
import onewire, ds18x20
In [26]:
# the device is on GPIO2
dat = machine.Pin(2)
# create the onewire object
ds = ds18x20.DS18X20(onewire.OneWire(dat))
# scan for devices on the bus
roms = ds.scan()
print('found devices:', roms)
found devices: [bytearray(b'(\xff8it\x16\x03$')]
In [27]:
x=roms[0]
num = x[0] << 8 | x[1] # "<<" operator równoważny mnożeniu x przez 2**y , "|" operator poziomu bitowego "lub"
num = x[0] * 256 + x[1]
print(num)
print(hex(num))
10495
0x28ff
Jeżeli 0x28 to jest to DS18B20 (jeżeli byłby 0x10 to DS18S20)
In [28]:
ds.convert_temp()
time.sleep_ms(750)
In [29]:
temp=ds.read_temp(roms[0])
print(temp)
31.5625
Wejście 1-Wire bez sterownika ds18x20¶
In [30]:
import machine,onewire
pin2 = machine.Pin(2)
ow=onewire.OneWire(pin2)
In [31]:
print(dir(ow))
['__class__', '__dict__', '__init__', '__module__', '__qualname__', 'crc8', 'readbit', 'readbyte', 'readinto', 'reset', 'scan', 'write', 'writebit', 'writebyte', 'SKIP_ROM', 'select_rom', 'pin', 'SEARCH_ROM', 'MATCH_ROM', '_search_rom']
In [32]:
from micropython import const
CONVERT = const(0x44)
RD_SCRATCH = const(0xbe)
WR_SCRATCH = const(0x4e)
ow.reset(True)
ow.select_rom(roms[0])
#ow.writebyte(0x4e) # write on scratchPad
config = b'\x00\x00\x7f' #12bit
#config = b'\x00\x00\x1f' #9bit
ds.write_scratch(roms[0],config)
#ow.writebyte(ow.SKIP_ROM)
ow.writebyte(CONVERT)
In [35]:
ow.buf = bytearray(12)
print(ow.buf)
ow.reset(True)
ow.select_rom(roms[0])
ow.writebyte(RD_SCRATCH)
ow.readinto(ow.buf)
print(ow.buf)
bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
bytearray(b'\xf9\x01\x00\x00\x7f\xffDD\x14\xff\xff\xff')
In [36]:
buf = ow.buf
print(buf)
for b in buf:
print(hex(b))
bytearray(b'\xf9\x01\x00\x00\x7f\xffDD\x14\xff\xff\xff')
0xf9
0x1
0x0
0x0
0x7f
0xff
0x44
0x44
0x14
0xff
0xff
0xff
Wyjaśnienie zapisu bitów i konwersji bitów np. https://www.thethingsnetwork.org/docs/devices/bytes.html
In [37]:
t = buf[1] << 8 | buf[0]
sign=t & 0x8000
if sign: # sign bit set
t = -((t ^ 0xffff) + 1)
temp = t/16
print(sign)
print(temp)
0
31.5625
MQTT¶
In [ ]:
%serialconnect to --port=COM6 --baud=115200
Podstawy¶
In [38]:
from umqtt.simple import MQTTClient
In [39]:
c = MQTTClient(client_id="isp_1", server="broker.hivemq.com", port=1883, keepalive=0)
In [ ]:
print(dir(c))
In [40]:
c.connect()
In [43]:
c.publish(b"isp/topic/1", "on - retain", retain=True)
In [44]:
def sub_cb(topic, msg):
print(msg)
c.set_callback(sub_cb)
c.subscribe(b"isp/topic/1")
print(c)
b'on - retain'
b'on - retain'
<MQTTClient object at 3fff05e0>
Przykład¶
In [48]:
import os
print(os.listdir())
['boot.py', 'do_connect.py']
In [47]:
%sendtofile do_connect.py
def do_connect():
import network
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
print('connecting to network...')
wlan.connect('Redmi', '')
while not wlan.isconnected():
pass
print('network config:', wlan.ifconfig())
Sent 10 lines (306 bytes) to do_connect.py.
In [49]:
%sendtofile MQTT_Light.py
from umqtt.simple import MQTTClient
import machine
import time
#c = MQTTClient(client_id, server, port=0, user=None, password=None, keepalive=0, ssl=False, ssl_params={}):)
c = MQTTClient(client_id="isp_1", server="broker.hivemq.com", port=1883, keepalive=0)
pinR=machine.Pin(15,machine.Pin.OUT)
pinG=machine.Pin(12,machine.Pin.OUT)
pinB=machine.Pin(13,machine.Pin.OUT)
pinButton=machine.Pin(4,machine.Pin.IN)
def sub_cb(topic, msg):
#print(msg)
pinR.off()
pinG.off()
pinB.on()
time.sleep_ms(200)
c.set_callback(sub_cb)
try:
c.connect()
c.subscribe(b"isp/topic/3")
pinR.off()
pinG.off()
pinB.off()
adc = machine.ADC(0)
while True:
c.check_msg()
time.sleep_ms(200)
a=adc.read()
#print(a)
c.publish(b"isp/topic/1", str(a))
p=pinButton.value()
print(p)
if p == 0:
c.publish(b"isp/topic/2", 'on')
pinB.on()
else:
c.publish(b"isp/topic/2", 'off')
pinB.off()
if a<200:
pinG.on()
else:
pinG.off()
finally:
c.disconnect()
pinR.on()
Sent 58 lines (1154 bytes) to MQTT_Light.py.
In [50]:
%sendtofile main.py
import do_connect
do_connect.do_connect()
import MQTT_Light
Sent 3 lines (60 bytes) to main.py.
In [54]:
print(os.listdir())
['boot.py', 'do_connect.py', 'MQTT_Light.py', 'main.py']
Do subskrypcji generowanych danych lub sterowania włączeniem diody należy wykorzystać wybranygo klienta MQTT:
- Klient MQTT na stronie WWW: http://www.hivemq.com/demos/websocket-client/
- Klient MQTT na Android: https://play.google.com/store/apps/details?id=snr.lab.iotmqttpanel.prod&hl=en
- Klient MQTT w Python: https://www.hivemq.com/blog/mqtt-client-library-paho-python/
In [ ]:
Powrót na stronę przedmiotu http://home.agh.edu.pl/~romanf/isp.html
In [ ]: