ESP32能够用与Arduino一样的价格来获得更多的功能, 包括WiFi/BLE/更多UART/更高速MCU(最高240MHz), 而且它除了C还支持Python.
ESP8266也可以用MicroPython, 还比ESP32便宜, 但是没有BLE, IO口更少, 并且MCU最高只能达到160MHz.
OS: Deepin Linux 15.11 Desktop, 自带Python2与Python3.
MicroPython固件刷写
详细可以参考http://docs.micropython.org/en/latest/esp32/quickref.html.
可以在MicroPython官网找到ESP32的固件, 建议下载Firmware with ESP-IDF v3.x中的第一个固件的二进制文件(*.bin).
刷写软件esptool为Python的一个包, 可以直接使用pip安装.
sudo apt update
sudo apt install -y python3-pip
sudo pip3 install esptool # sudo pip install esptool也可以
然后就可以烧写啦, 命令如下, port参数要自己调整, 在GNU/Linux系统中一般是/dev/ttyUSB0(连了多个MCU的话可能就成了/dev/ttyUSB1之类的, 数字依次增大), Windows系统中一般为COM3(可以在设备管理器中查找是COM几).
esptool.py --chip esp32 --port /dev/ttyUSB0 erase_flash # 擦除原固件
esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 460800 write_flash -z 0x1000 固件bin文件路径
烧写完后用PuTTY, 设置串口Serial为上述port参数的内容, 波特率为115200即可登录REPL(Python的交互式编程环境).
我用的是kermit.
# 安装
sudo apt install -y ckermit
# 配置
cd ~
echo 'set line /dev/ttyUSB0' >> .kermrc # 如果后续连接失败, 把ttyUSB0换成ttyUSB1之类的
echo 'set speed 115200' >> .kermrc
echo 'set carrier-watch off' >> .kermrc
echo 'set handshake none' >> .kermrc
echo 'set flow-control none' >> .kermrc
echo 'robust' >> .kermrc
echo 'set file type bin' >> .kermrc
echo 'set file name lit' >> .kermrc
echo 'set rec pack 1000' >> .kermrc
echo 'set send pack 1000' >> .kermrc
echo 'set window 5' >> .kermrc
echo 'c' >> .kermrc
# 运行
cd ~
kermrc
我最初发现自己无法使用esptool, 后来发现是我在
~/.zshrc中配置了alias -s py=vi, 所以直接写esptool.py时shell不会运行它反而调用vi编辑它. 聪明反被聪明误啊.
Mu安装与使用.
ampy
不像其余的MicroPython开发板, ESP32并不会虚拟为存储设备出现在文件管理器中. 那么除了直接在REPL用Python命令写入Python脚本外, 就得另想办法写入Python脚本了.
幸运的是我们有一个叫做ampy的Python包搞定了ESP32中Python脚本的存取操作问题, 但是它其实还是调用REPL, 不过将相关的命令自动执行了, 所以使用ampy时候不能开着PyTTY等软件占用着REPL.
# 安装
sudo pip3 install ampy
# 发送文件到ESP32
ampy --port /dev/ttyUSB0 put 文件路径
# 删除ESP32上的文件
ampy --port /dev/ttyUSB0 rm ESP32上的文件名
# 不上传, 直接在ESP32上运行脚本
ampy --port /dev/ttyUSB0 run 脚本路径
注意MicroPython解释器会在单片机上电时候先运行boot.py, 再运行main.py, 这个过程可以在REPL中检查与打断. 可以把一些”系统设置”写在boot.py里.
Mu
上述方法好麻烦啊, 有没有一体化的简介的解决方案呢?
这就是正主Mu, 自动识别连接的串口, 包含ESP32文件管理器, 自动补全代码的Python编辑器, 还可以进行Pypi的第三方包管理(虽然这个功能很垃圾)…
# 安装
git clone https://github.com/mu-editor/mu.git
sudo pip install --upgrade pip
cd mu
sudo pip3 install -e ".[dev]"
# 运行
python3 mu路径/run.py
在mu路径下的conf目录中有一个mu.codewith.editor.desktop文件(在文件管理器中看见的名字是mu), 可以把这个文件复制到桌面以脱离命令行图形化打开. 也可以把这个文件复制到/usr/local/share/applications/(需要root权限), 这样就可以在启动器中找到它了.
webrepl
Mu是好, 但是使用时候还是需要用线连接ESP32. 为了摆脱实体线的束缚, 可以改用WiFi网络进行repl控制以及文件传输, 即webrepl.
将下述代码添加到boot.py中, 连上串口启动一次, 会提示输入WiFi ssid与密码, 连接好后会提示需要运行import webrepl_setup, 运行后输入E自启动webrepl, 设置密码, 再然后复位(重启)ESP32, 即可在repl中观察到WebREPL daemon started on ws://192.168.x.xxx:8266.
去http://micropython.org/webrepl/, 输入上述地址即可远程控制ESP32, 也能够进行文件传输.
也可以用wget -r直接把webrepl的网页端下到自己电脑上用.
def is_legal_wifi(essid, password):
'''
判断WIFI密码是否合法
'''
if len(essid) == 0 or len(password) == 0:
return False
return True
def do_connect():
import json
import network
# 尝试读取配置文件wifi_confi.json,这里我们以json的方式来存储WIFI配置
# wifi_config.json在根目录下
# 若不是初次运行,则将文件中的内容读取并加载到字典变量 config
try:
with open('wifi_config.json','r') as f:
config = json.loads(f.read())
# 若初次运行,则将进入excpet,执行配置文件的创建
except:
essid = ''
password = ''
while True:
essid = input('wifi name:') # 输入essid
password = input('wifi passwrod:') # 输入password
if is_legal_wifi(essid, password):
config = dict(essid=essid, password=password) # 创建字典
with open('wifi_config.json','w') as f:
f.write(json.dumps(config)) # 将字典序列化为json字符串,存入wifi_config.json
break
else:
print('ERROR, Please Input Right WIFI')
#以下为正常的WIFI连接流程
wifi = network.WLAN(network.STA_IF)
if not wifi.isconnected():
print('connecting to network...')
wifi.active(True)
wifi.connect(config['essid'], config['password'])
import utime
for i in range(200):
print('第{}次尝试连接WIFI热点'.format(i))
if wifi.isconnected():
break
utime.sleep_ms(100) #一般睡个5-10秒,应该绰绰有余
if not wifi.isconnected():
wifi.active(False) #关掉连接,免得repl死循环输出
print('wifi connection error, please reconnect')
import os
# 连续输错essid和password会导致wifi_config.json不存在
try:
os.remove('wifi_config.json') # 删除配置文件
except:
pass
do_connect() # 重新连接
else:
print('network config:', wifi.ifconfig())
if __name__ == '__main__':
do_connect()
import webrepl # 开启webrepl
webrepl.start() # 开启webrepl
使用时的碎碎念
点亮D15与GND之间的LED.
import machine
import time
d15=machine.Pin(15,machine.Pin.OUT)
d15.value(1)
注意在针脚没有设置为machine.Pin.OUT的时候其上有微弱的电压, 可以让某些LED发一点点光, 设置后就没有了, 直到给它赋高电压针脚.value(1). 设置为machine.Pin.IN的针脚上也有电压, 可以点亮某些LED, 如果不接地的话读出的数值也为1针脚.value().