刷入固件

准备

  1. 使用 USB 连接 NodeMCU 到 PC
  2. 下载 MicroPython for ESP8266 的固件
  3. 下载安装 CP210x_Windows_Drivers
  4. 使用 pip 安装 esptool 和 ampy

擦除Flash

  1. 在设备管理器中找到串口连接串口号(比如 COM3)
  2. 运行esptool.py --port COM3 erase_flash把先前固件的数据都删掉,防止出现一些问题
    运行正确的话输出如下
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $ esptool.py --port COM3 erase_flash
    esptool.py v2.1
    Connecting....
    Detecting chip type... ESP8266
    Chip is ESP8266
    Uploading stub...
    Running stub...
    Stub running...
    Erasing flash (this may take a while)...
    Chip erase completed successfully in 10.6s
    Hard resetting...

刷入

  1. 运行esptool.py --port COM3 write_flash -fm qio 0x00000 esp8266-20170823-v1.9.2.bin
    默认的-fm写入模式是dio对于大于 4M 的 Flash 会有更好的兼容,但是速率受限。

    multi I/O SPI设备是有从单一设备支持增加带宽或throughput的能力。相对于标准的串行Flash存储设备,一个dual I/O接口能够使能双倍的速率。quad I/O接口能提升throughput四次。

  2. 运行成功的输出如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    $ esptool.py --port COM3 write_flash -fm qio 0x00000 esp8266-20170823-v1.9.2.bin
    8266-20170823-v1.9.2.bin
    esptool.py v2.1
    Connecting....
    Detecting chip type... ESP8266
    Chip is ESP8266
    Uploading stub...
    Running stub...
    Stub running...
    Configuring flash size...
    Auto-detected Flash size: 4MB
    Flash params set to 0x0240
    Compressed 601136 bytes to 392067...
    Wrote 601136 bytes (392067 compressed) at 0x00000000 in 34.7 seconds (effective 138.7 kbit/s)...
    Hash of data verified.

    Leaving...
    Hard resetting...
  3. 按下板子的 RST 键重启

REPL

REPL — 交互式解释器环境。
R(read)、E(evaluate)、P(print)、L(loop)
输入值,交互式解释器会读取输入内容并对它求值,再返回结果,并重复此过程。

Micropython 提供REPL,但是为了能够人机交互,需要其他的软件接收信号发送给开发板。

putty

  1. 设置串口号和波特率
设置串口号和波特率
设置串口号和波特率
  1. 设置其他参数
设置其他参数
设置其他参数
  1. 打开连接
    1
    2
    3
    4
    5
    6
    7
    l▒"rdr$r▒n▒▒▒▒▒oܟ▒▒#r▒▒b쏜#$▒#$▒▒l#$▒▒ln▒p{l▒l▒▒|▒▒▒#4 ets_task(40100164, 3, 3fff837c, 4)
    OSError: [Errno 2] ENOENT

    MicroPython v1.9.2-8-gbf8f45cf on 2017-08-23; ESP module with ESP8266
    Type "help()" for more information.
    >>> help()
    Welcome to MicroPython!

ampy

Adafruit MicroPython Tool 通过串口连接 MicroPython 单板的的工具,支持获取、罗列、删除、提交文件以及运行脚本的功能。

  1. 运行ampy --port COM3 get boot.py获取boot.py的内容
    1
    2
    3
    4
    5
    6
    7
    8
    $ ampy --port COM3 get boot.py
    # This file is executed on every boot (including wake-boot from deepsleep)
    #import esp
    #esp.osdebug(None)
    import gc
    #import webrepl
    #webrepl.start()
    gc.collect()

或者设置终端的环境变量export AMPY_PORT=COM3(Windows CMD: set AMPY_PORT=COM3)指定端口

1
$ ampy get boot.py

node-serialport

一个 Node.js 库,支持Linux、Windows和MacOS,使用 Javascript 事件驱动编程,支持命令行打开模拟终端连接串口

  1. 罗列所有串口

    1
    2
    PS C:\>serialport-term.cmd
    COM3 USB\VID_10C4&PID_EA60\0001 Silicon Labs
  2. 进入终端

    1
    2
    3
    4
    5
    6
    PS C:\>serialport-term.cmd -p COM3 -b 115200
    l▒"rdr$r▒n▒▒▒▒▒oܟ▒▒#r▒▒b쏜#$▒#$▒▒l#$▒▒ln▒p{l▒l▒▒|▒▒▒#4 ets_task(40100164, 3, 3fff837c, 4)
    OSError: [Errno 2] ENOENT

    MicroPython v1.9.2-8-gbf8f45cf on 2017-08-23; ESP module with ESP8266
    Type "help()" for more information.

使用 MicroPython 进行编程

// TODO

串口编程

使用 node-serialport

  1. 使用process.stdin.setRawMod(true)获取所有按键输入,包括控制按键等,实现串口连接的模拟终端
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    const PORT_NAME = 'COM3'
    const BAUD_RATE = 115200 // config those

    const colors = require('colors')
    const SerialPort = require('serialport');
    const port = new SerialPort(PORT_NAME, {
    baudRate: 115200,
    autoOpen: false,
    rtscts: true
    });

    const itOut = (data) => {
    process.stdout.write(data.toString())
    }

    const itError = (data) => {
    process.stdout.write(data.toString())
    }
    port.open(e => {
    port.write('import os;os.listdir()\r') // '\r' is return means next line, in Windows is '\r\n'

    port.on('error', err => {
    itError(err)
    })

    port.on('end', (s) => {
    port.flush()
    port.close();
    })


    port.on('readable', function () {
    itOut(port.read())
    });

    process.stdin.setRawMode(true)
    let exitCounter = 0
    process.stdin.on('data', (s) => {
    if (s[0] === 0x03) {
    if (exitCounter == 1) {
    itOut('bye\n')
    port.close();
    process.exit(0);
    } else {
    itOut('Wanna exit? ctrl+c continue.\n')
    port.write(s) // ctrl+c 终止当前运行的程序
    exitCounter++;
    }
    } else {
    exitCounter = 0
    port.write(s)
    }
    if (s[0] === 0x0d) {
    itOut('\n')
    }
    });
    })

non-blocking input | raw input

类似 node.js process.stdin.setRawMode(true) 的操作,不需要回车,获取所有包括ctrl+B等不可见字符

  • Python
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    # 参考 Django createsuperuser 的时候输入密码的功能
    import platform
    from sys import stdout


    class Getcher:
    def __init__(self):
    self.__getch = None
    if platform.system() == 'Windows':
    import msvcrt

    def getch_func():
    return int.from_bytes(msvcrt.getch(), byteorder='little')
    self.__getch = getch_func
    else:
    def getch_func_cursor():
    import curses

    window = curses.initscr()
    curses.noecho()
    window.keypad(True)

    def getch_func():
    try:
    stdout.write('\r') # return line first position
    key = window.getch()
    return key
    except KeyboardInterrupt:
    curses.endwin()
    return 3
    except Exception:
    curses.endwin()
    return getch_func

    self.__getch = getch_func_cursor()

    def getch(self):
    return self.__getch()


    g = Getcher()

    while True:
    k = g.getch()
    if k == 3:
    exit(0)
    print(chr(k))