分享

ESP32+Thonny+固件烧录+编写建议

 云深无际 2021-11-03
https://micropython.org/download/esp32/

http://www.netbian.com/desk/23211.htm


我们此次的主角

这个实在是太新了,我不敢用

我们下载这个

https://micropython.org/resources/firmware/esp32-idf3-20210202-v1.14.bin
http://docs.micropython.org/en/latest/

然后把我的秃头鸭拿出来,秃头保平安

https://thonny.org/

我们下载这个软件

https://github-releases.githubusercontent.com/163728962/a2487d00-755d-11eb-8f46-001a6cb020d5?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20210301%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20210301T111206Z&X-Amz-Expires=300&X-Amz-Signature=d51ba988a6cf3969dfaaaa6be70a87cb61f4a380fd781e31582d9d165b8bf0f5&X-Amz-SignedHeaders=host&actor_id=36230576&key_id=0&repo_id=163728962&response-content-disposition=attachment%3B%20filename%3Dthonny-3.3.5.exe&response-content-type=application%2Foctet-stream

下一步

完成

选择中文,标准

选择这里

我们在这里选择32

右下角,我们来烧录一下我们上面下载的固件

安装

稍等片刻

就看到这个了,我们现在已经可以开始开发了

在编辑区可以使用补全功能

我们可以有选择的打开一些窗口

可以打开一个程序树图,这里我们程序太短看不出来

也可以看到栈结构.可以用列表来构建



这里使用 WiFi 管理器库,就不必再硬编码网络凭据了。ESP32 设置一个接入点,显示可用的 Wi-Fi 网络。只需要选择您的网络并输入密码即可将ESP32设置为Wi-Fi站。

import networkimport socketimport ureimport time
ap_ssid = "ESP32"ap_password = "12345678"ap_authmode = 3 # WPA2
NETWORK_PROFILES = 'wifi.dat'
wlan_ap = network.WLAN(network.AP_IF)wlan_sta = network.WLAN(network.STA_IF)
server_socket = None

def get_connection(): """return a working WLAN(STA_IF) instance or None"""
# First check if there already is any connection: if wlan_sta.isconnected(): return wlan_sta
connected = False try: # ESP connecting to WiFi takes time, wait a bit and try again: time.sleep(3) if wlan_sta.isconnected(): return wlan_sta
# Read known network profiles from file profiles = read_profiles()
# Search WiFis in range wlan_sta.active(True) networks = wlan_sta.scan()
AUTHMODE = {0: "open", 1: "WEP", 2: "WPA-PSK", 3: "WPA2-PSK", 4: "WPA/WPA2-PSK"} for ssid, bssid, channel, rssi, authmode, hidden in sorted(networks, key=lambda x: x[3], reverse=True): ssid = ssid.decode('utf-8') encrypted = authmode > 0 print("ssid: %s chan: %d rssi: %d authmode: %s" % (ssid, channel, rssi, AUTHMODE.get(authmode, '?'))) if encrypted: if ssid in profiles: password = profiles[ssid] connected = do_connect(ssid, password) else: print("skipping unknown encrypted network") else: # open connected = do_connect(ssid, None) if connected: break
except OSError as e: print("exception", str(e))
# start web server for connection manager: if not connected: connected = start()
return wlan_sta if connected else None

def read_profiles(): with open(NETWORK_PROFILES) as f: lines = f.readlines() profiles = {} for line in lines: ssid, password = line.strip("\n").split(";") profiles[ssid] = password return profiles

def write_profiles(profiles): lines = [] for ssid, password in profiles.items(): lines.append("%s;%s\n" % (ssid, password)) with open(NETWORK_PROFILES, "w") as f: f.write(''.join(lines))

def do_connect(ssid, password): wlan_sta.active(True) if wlan_sta.isconnected(): return None print('Trying to connect to %s...' % ssid) wlan_sta.connect(ssid, password) for retry in range(100): connected = wlan_sta.isconnected() if connected: break time.sleep(0.1) print('.', end='') if connected: print('\nConnected. Network config: ', wlan_sta.ifconfig()) else: print('\nFailed. Not Connected to: ' + ssid) return connected

def send_header(client, status_code=200, content_length=None): client.sendall("HTTP/1.0 {} OK\r\n".format(status_code)) client.sendall("Content-Type: text/html\r\n") if content_length is not None: client.sendall("Content-Length: {}\r\n".format(content_length)) client.sendall("\r\n")

def send_response(client, payload, status_code=200): content_length = len(payload) send_header(client, status_code, content_length) if content_length > 0: client.sendall(payload) client.close()

def handle_root(client): wlan_sta.active(True) ssids = sorted(ssid.decode('utf-8') for ssid, *_ in wlan_sta.scan()) send_header(client) client.sendall("""\ <html> <h1 style="color: #5e9ca0; text-align: center;"> <span style="color: #ff0000;"> Wi-Fi Client Setup </span> </h1> <form action="configure" method="post"> <table style="margin-left: auto; margin-right: auto;"> <tbody> """) while len(ssids): ssid = ssids.pop(0) client.sendall("""\ <tr> <td colspan="2"> <input type="radio" name="ssid" value="{0}" />{0} </td> </tr> """.format(ssid)) client.sendall("""\ <tr> <td>Password:</td> <td><input name="password" type="password" /></td> </tr> </tbody> </table> <p style="text-align: center;"> <input

注意里面改自己的连接信息

ctrl+S,保存在外部设备

注意这个名字,我写错了.按照我下面的来

改成这个上传

import wifimgrfrom time import sleepimport machine
try: import usocket as socketexcept: import socket
led = machine.Pin(2, machine.Pin.OUT)
wlan = wifimgr.get_connection()if wlan is None: print("Could not initialize the network connection.") while True: pass # you shall not pass :D
# Main Code goes here, wlan is a working network.WLAN(STA_IF) instance.print("ESP OK")
def web_page(): if led.value() == 1: gpio_state="ON" else: gpio_state="OFF" html = """<html><head> <title>ESP Web Server</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" href="data:,"> <style>html{font-family: Helvetica; display:inline-block; margin: 0px auto; text-align: center;} h1{color: #0F3376; padding: 2vh;}p{font-size: 1.5rem;}.button{display: inline-block; background-color: #e7bd3b; border: none; border-radius: 4px; color: white; padding: 16px 40px; text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;} .button2{background-color: #4286f4;}</style></head><body> <h1>ESP Web Server</h1> <p>GPIO state: <strong>""" + gpio_state + """</strong></p><p><a href="/?led=on"><button class="button">ON</button></a></p> <p><a href="/?led=off"><button class="button button2">OFF</button></a></p></body></html>""" return html try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(('', 80)) s.listen(5)except OSError as e: machine.reset()
while True: try: if gc.mem_free() < 102000: gc.collect() conn, addr = s.accept() conn.settimeout(3.0) print('Got a connection from %s' % str(addr)) request = conn.recv(1024) conn.settimeout(None) request = str(request) print('Content = %s' % request) led_on = request.find('/?led=on') led_off = request.find('/?led=off') if led_on == 6: print('LED ON') led.value(1) if led_off == 6: print('LED OFF') led.value(0) response = web_page() conn.send('HTTP/1.1 200 OK\n') conn.send('Content-Type: text/html\n') conn.send('Connection: close\n\n') conn.sendall(response) conn.close() except OSError as e: conn.close() print('Connection closed')

同理把这个也上传

然后电脑上面可以看到

接着输入这个IP就会出现

最后附上一张流程图


import time
time.sleep(1) # sleep for 1 secondtime.sleep_ms(500) # sleep for 500 millisecondstime.sleep_us(10) # sleep for 10 microsecondsstart = time.ticks_ms() # get value of millisecond counterdelta = time.ticks_diff(time.ticks_ms(), start)  # compute time difference
https://docs.singtown.com/micropython/zh/latest/pyboard/pyboard/quickref.html

可以写一些延时的代码

https://docs.python.org/3/reference/index.html

如果你是一个小白,我觉得以上的网站就很适合你


在编写中断程序的时候可以按照以下的建议来编写

  • 尽量使代码短而简单。

  • 避免内存分配:无附加列表或插入字典,无浮点数。

  • 在ISR返回多个字节的情况下,使用预先分配的 bytearray 。若在ISR何主程序之间共享多个整数,则使用数组( array.array )。

  • 在主程序和ISR之间共享数据的情况下,考虑在主程序中访问数据前禁用中断,并在此后立即重新启。

  • 分配紧急异常缓冲区

这就是缓存区

由于各种原因,保持ISR代码尽可能简短十分重要。其应在事件发生后;自己执行:可延迟的操作应委托给主程序循环。典型情况下,一个ISR将处理引起中断的硬件设备,为下一个中断做好准备。ISR将与主循环通信,通过更新共享数据来表明中断已发生, 并返回。ISR应尽快将控制权返还给主循环。

ISR和主程序间的通信

通常,ISR需与主程序通信。最简单的通信方式是通过一个或多个共享数据对象,申明为全局或通过一类共享(见下)。但是这种方法有很多局限性和危害,下面将进行详细介绍。整数、 bytes 和 bytearray 对象以及数组(来自数组模块,可储存多种数据类型)通常用于此目的。

创建Python对象

ISR无法创建Python对象的实例。这是由于MicroPython需从称为堆的空闲内存块的存储中为对象分配内存。这在中断处理程序中是不允许的,因为堆分配并非可重入的。换言之,当主程序正在执行分配时, 中断可能发生-为保持堆的完整性,解释器不允许ISR代码中的内存分配。

其影响之一为ISR无法使用浮点数算法;这是因为浮点数为Python对象。类似地,ISR无法附加项目到列表中。在实际操作中,很难精准确定哪个代码结构将尝试执行内存分配并引发错误信息:使ISR代码尽可能简短的另一原因。

避免此类问题的一个方法是ISR使用预分配缓冲区。例如,一个类构造函数创建一个 bytearray 实例和一个布尔标志。ISR方法将数据分配到缓冲区中的 位置并设置标志。当实例化对象时,内存分配在主程序代码中实现,而非在ISR中。

MicroPython库I/O方法通常提供使用预分配缓冲区的选项。

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多