如何在20元小板子上跑Python

如何在20元小板子上跑Python

6 年前 · 来自专栏 蛇之魅惑

如今物联网技术风生水起,Python也要多凑热闹。

=========================================================================================================================================================================================================

MicroPython项目自2014年启动,旨在低廉嵌入式系统上以固件形式运行Python。MicroPython的官方开发板是一块基于STM32的SoC,然而,这块开发板的价格一直居高不下,在某宝上买要将近200块。然而,最新的树莓派Zero也才150块钱,而树莓派是支持通用Linux的,比嵌入式固件不知道高明到哪里去了。

2014年8月,位于上海的乐鑫公司推出了针对物联网终端应用的ESP8266 SoC,这款芯片自带WiFi和硬件加速的TCP/IP协议栈,价格非常低廉。连同开发板(NodeMCU)在淘宝上的零售价不超过20元,价格直逼Arduino小板。除了官方提供的基于C语言的SDK外,NodeMCU项目提供了基于Lua语言的脚本式开发环境。此外,这块芯片也可以烧录AT协议的固件,在系统中充当一块无线网卡。

虽然Lua是一门很棒的语言,但和TIOBE常年top10的Python相比,依然相对小众。2016年5月,1.8版本的MicroPython开始提供对ESP8266芯片的支持,这意味着,更多的开发者可以使用自己熟悉的语言,以极低成本制作一套物联网终端。

本文简单介绍如何在ESP8266开发板上运行MicroPython。

1. 购买开发板

在某宝上以NodeMCU为关键字,即可发现ESP8266开发板。因为它太便宜,往往不抵运费合算。所以可以选择一些大一点的商家,根据自己的需要配置一些发光二极管、面包板、杜邦线之类的配件。当然也可以购买一些板载继电器、温度传感器之类的实验板供把玩。

2. 安装驱动程序

如果你购买了NodeMCU,或者NodeMCU兼容的开发板,首先需要安装串口转USB的驱动。如果你用的是Linux或者macOS,系统通常自带了驱动。如果你的系统是Windows,则需要根据转换器的型号去官网下载驱动程序。比如通常买的这款NodeMCU,其转换器型号为CP2102,则去Silicon Lab的官网下载。

USB to UART Bridge VCP Drivers

安装完驱动后,把开发板用Micro USB线连接到电脑上。然后用 这篇文章 的方法找到开发板对应的串口名称。下文中以 <serial_port> 代之。

3. 安装工具软件

在电脑上安装Python,或者利用系统自带的Python。如今NodeMCU的开发工具已经在pip中。执行以下命令即可

pip install esptool -U

此外,还需要一个串口终端。在Linux下可以使用系统自带的minicom,macOS下可以使用系统自带的screen,或者安装一个minicom,Windows下可以使用putty

PuTTY Download Page

4. 烧录MicroPython固件

此处 可以得到官方最新发布的MicroPython/ESP8266固件。笔者下载的是esp8266-20161110-v1.8.6.bin

运行以下命令可以将固件下载到开发板中

$ esptool.py --port <serial_port> erase_flash
$ esptool.py --port <serial_port> --baud 460800 write_flash --
flash_size=detect 0 esp8266-20161110-v1.8.6.bin --verify

这个下载命令与官方命令稍有区别。笔者强烈的建议:

  1. 在烧录固件之前erase_flash,尤其是对于一些烧录过其他固件的旧开发板。
  2. 烧录命令增加 --verify选项进行校验。

5. 连接开发板,得到Python Shell

使用minicom的用户,运行以下命令

sudo minicom -s

在其后的菜单里,选择串口为连接开发板的串口,波特率115200

使用screen的用户,运行以下命令

screen <serial_port> 115200

使用putty的用户,按以下设置:

连接完成后,按开发板的复位键,得到Python Shell

6. 硬件操作实战

虽然,在树莓派里也可以通过gpio库操作树莓派的IO,但这里与树莓派的区别是,MicroPython是 实时 的,也就是说,从下达软件指令到硬件电路做出响应,其时间是确定的。

使用MicroPython操作IO的时候需注意,MicroPython的固件是针对ESP8266的,不是针对NodeMCU的,因此,其Pin的编号是ESP8266的GPIOx,而不是NodeMCU板子上的Dx。下面的例子就是对板载LED进行操作。NodeMCU文档有这样一个表格:

对于LED,若用Lua操作,则需要操作Pin 0,若用MicroPython操作,则需要操作Pin 16。

7. WiFi温度传感器

下面利用MicroPython/ESP8266制作一个WiFi温度传感器。

我们需要准备的硬件除了NodeMCU开发板之外,还需要一个温度传感器。DHT系列是一种比较常用的廉价温度传感器模组,笔者手头有一只DHT11模组,大概4块钱买的。

DHT11是单线数字信号,其协议并不是I2C、SPI之类的标准协议。好在MicroPython内建了DHT协议的支持。像这样就可以读温度传感器的值了:

import dht
PIN_DHT = 14 #(GPIO14/D5)
d = dht.DHT11(machine.Pin(PIN_DHT))
d.measure()
print(d.temperature())

这样的代码量,少得几乎不能再少。

下面把完整的代码贴出来,保存为 dht_server.py

import dht
import machine
import usocket as socket
import network
SSID = 'YOUR_WIFI_SSID'
SSID_PW = 'YOUR_WIFI_PASSWORD'
def do_connect():    
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    if not wlan.isconnected():
        wlan.connect(SSID,SSID_PW)
        while not wlan.isconnected():
    return wlan.ifconfig()
def read_dht():
    PIN_DHT = 14
    d = dht.DHT11(machine.Pin(PIN_DHT))
    d.measure()
    return d.temperature()
def do_server(ip,port):
    CONTENT = """\
HTTP/1.0 200 OK
Content-Type: application/json
    "data" : %d
    ai = socket.getaddrinfo(ip,port)
    addr = ai[0][4]
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind(addr)
    s.listen(5)
    while True:
        res = s.accept()
        client_s = res[0]
        client_addr = res[1]
        req = client_s.recv(4096)
        parts = req.decode('ascii').split(' ')
        if parts[1] == '/temperature':
            client_s.send(bytes(CONTENT % read_dht(), "ascii"))
        client_s.close()