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

Skrótowy opis:

  1. Należy zainstalować wybraną dystrybucję Python (polecam ANACONDA lub MINICONDA)
  2. Pobrać ostatnie firmware http://micropython.org/download#esp8266
  3. 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

  1. 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 analogowe

In [22]:
adc = machine.ADC(0)
In [24]:
a=adc.read()
print(a)
128

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:

In [ ]:

Powrót na stronę przedmiotu http://home.agh.edu.pl/~romanf/isp.html

In [ ]: