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的第三方包管理(虽然这个功能很垃圾)…

详见https://mu.readthedocs.io/en/latest/

# 安装
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的网页端下到自己电脑上用.

详见https://www.jianshu.com/p/0613f3f3f4ba

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().



software 单片机 Python hardware ESP

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!