前言

我们在 MicroBlocks 编程案例: dotPack 讨论了如何使用 MicroBlocks 在 dotPack 上制造"雪崩"

本文将展示在 dotPack 上制造"雪崩"的各种方法:

  • MicroBlocks
  • C/C++/Arduino
  • MicroPython/CircuitPython
  • MicroBlocks 固件 + Python 客户端
  • 官方固件 + Python 客户端
  • 官方固件 + Scratch
  • 官方固件 + 浏览器里的 JavaScript
  • 官方固件 + 浏览器中的 Python(PyScript/Pyodide)
  • MicroBlocks 固件 + Squeak(Smalltalk) 客户端
  • 待定…
    • LISP(ulisp)
    • Javascript
    • DeviceScript
    • Lua
    • Rust
    • Ruby
    • Toit
    • Prolog
    • Forth
    • Nim

在硬件层面了解 dotPack

为了在不同的编程语言中对 dotPack 进行编程,我们有必要在硬件层面了解一下 dotPack。

就可编程部分来说, dotPack 是一个由 ESP32 驱动的 16x16 NeoPixel 点阵屏, 控制引脚(Pin)为 12

NeoPixel 点阵屏采用 S 形走线方式。

在硬件层面,这个看起来像二维平面的点阵屏,实际是一条一维的 S 形 NeoPixel 灯带。如果你打算自己写底层固件,则一维坐标到二维平面坐标(x,y)的转化,需要自己完成。若使用官方固件,它已经为你完成了这个工作。

制造"雪崩"的 N 种方法

MicroBlocks

接下来,我们将使用 2 种不同的积木库,在 dotPack 上制造雪崩。

  • 内置的 NeoPixel 库: 一维坐标
  • 内置的 NeoPanel 库: 二维坐标, 完全在 MicroBlocks 中实现, 底层基于 NeoPixel 库

在开始制造雪崩之前,我们需要做些准备工作,将 dotPack 接入到 MicroBlocks 编程平台上。

刷入固件

为了使用 MicroBlocks 对 dotPack 编程,首先需要为 dotPack 刷入新的固件, 替代内置的官方固件。

这一过程十分简单,在 MicroBlocks 编程环境里(浏览器)即可完成所有操作:

  • 将 dotPack 连接到计算机(如果无法发现设备端口, 则需要安装 CH340 驱动)
  • 点击左上角设置按钮(齿轮 ⚙️ 图标)
  • 点击升级主板固件
  • 点击 ESP32
  • 等待完成。
    • 提醒: 使用 MicroBlocks 网页刷入 ESP32 固件时,请确保网页处于工作状态,耐心等待完成,不要切换到其他页面,否则会导致刷入的固件不完整。

完成之后,点击页面上方的 USB 图标,点击书包的串口地址,即可将 dotPack 接入硬件编程平台。

如果遇到问题,可以重新插拔下 dotPack 的 usb 线,并刷新下编程页面。

接下来就可以开始制造雪崩了!

方法 1: 内置的 NeoPixel 库: 一维坐标

首先打开内置的 NeoPixel 库

开始编程:

查看/编辑 程序

方法 2: 内置的 NeoPanel 库

查看/编辑 程序

方法 3: C/C++/Arduino

接下来让我们采用 Arduino 平台制造"雪崩". 我选择 PlatformIO 编程环境。

这可能是硬件编程领域最主流的做法。

 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
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>

#define PackPIN 12

// https://learn.adafruit.com/adafruit-neopixel-uberguide/neomatrix-library
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(16, 16, PackPIN,
                                               NEO_MATRIX_TOP + NEO_MATRIX_LEFT +
                                                   NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG,
                                               NEO_GRB + NEO_KHZ800);

void setup()
{
  // put your setup code here, to run once:
  matrix.begin();
  matrix.setBrightness(20);
}

void loop()
{
  // put your main code here, to run repeatedly:
  for (int i = 0; i < 16; ++i)
  {
    for (int j = 0; j < 16; ++j)
    {
      if (rand() % 2 == 0)
      {
        matrix.drawPixel(i, j, matrix.Color(0, 0, 0));
      }
      else
      {
        matrix.drawPixel(i, j, matrix.Color(255, 255, 255));
      }
    }
  }

  matrix.show();
  delay(100);
}

项目源码已经放到 Github: dotPack-Arduino

如果你选择 Arduino IDE 作为 Arduino 编程环境, 可参考Installing ESP32 Board in Arduino IDE 2.0

方法 4: MicroPython

在此使用 Thonny 编辑器。

为了使用 MicroPython 对 dotPack 编程,首先需要往 dotPack 刷入 MicroPython 固件。在 Thonny 编辑器中刷入固件的方法是:

  • 打开 运行 > 配置解释器
  • 点击右下角的 安装或升级固件
  • 下载最新MicroPython ESP32 固件,并选择它

点击安装,等待完成。

之后就可以在 Thonny 里使用 MicroPython 对 dotPack 编程了。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# https://docs.micropython.org/en/latest/esp32/quickref.html#neopixel-and-apa106-driver
import time
import random
from machine import Pin
from neopixel import NeoPixel

pin = Pin(12, Pin.OUT)   # set GPIO12 to output to drive NeoPixels
np = NeoPixel(pin, 256)   # create NeoPixel driver on GPIO12 for 256 pixels
while True:
    for i in range(256):
        if random.choice([True, False]) == True:
            np[i] = (255//5, 255//5, 255//5) # set the first pixel to white
        else:
            np[i] = (0, 0, 0) # set the first pixel to black
    np.write()              # write data to all pixels
    time.sleep(0.1)

值得注意的是,如果将 LED 开得过亮,过大的功耗会导致 ESP32 停机(出于保护目的)。这行代码用于调整亮度(最大亮度的 1/5): np[i] = (255//5, 255//5, 255//5)

方法 5: MicroBlocks 固件 + Python 客户端

首先需要在 MicroBlocks 中往 dotPack 刷入 MicroBlocks 固件 (这个固件的 dotPack 驱动是早期版本,可能已经失效)。在 MicroBlocks 中配置好 WIFI 之后,你可以看到 dotPack 的 IP,之后我们在 Python 客户端中通过这个 IP 连接 dotPack,并对其编程。

 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
import random
from dotpack import DotPack, Animation

pack = DotPack()
# 在 microblocks 里查看 IP
address = '172.20.10.2'
pack.connect(address)# 输入书包 address 可连接到书包
# 创建动画对象
animation = Animation()

# 生成10张雪崩图像
for x in range(10):
    # 创建一张雪崩图像
    for i in range(16):
        for j in range(16):
            if random.choice([True, False]):
                pack.set_pixel(i, j, 'white', show=False)
            else:
                pack.set_pixel(i, j, 'black', show=False)
    # 将雪崩图像添加到动画
    animation.add_frame(pack)

# 在 JupyterLab 编辑器中预览动画
animation.show()

# 将动画上传到 dotPack (默认开机启动它)
animation.show(to_pack=pack)

方法 5: 官方固件 + Python 客户端

如果你之前将固件刷为了第三方固件(如MicroBlocks/MicroPython),需要将固件重新刷回官方固件, 方法如下:

  1. 下载 dotPack-V1.36固件
  2. 断开 dotPack 与任何编程环境的连接
  3. 使用固件烧录工具 刷入前边下载的固件(按 Program 开始刷入)。

烧录的过程不要离开当前页面。完成之后断开连接,重新插拔板子 USB 接口

如果一切正常,你应该能够在板子上看到滚动显示的 “dotPack”。

接下来我们就可以使用 Python 客户端对其进行编程了。

推荐使用 JupyterLab 作为编程环境。

开始之前,需要先在 JupyterLab 中安装 dotpack 库: !pip install dotpack

为了对 dotPack 进行编程,首先需要知道它的蓝牙地址, 书包里有一个铭牌写了书包地址. 也可以通过以下脚本发现书包的蓝牙地址:

1
2
3
4
5
6
7
8
9
import asyncio
from bleak import BleakScanner

async def main():
    devices = await BleakScanner.discover()
    for d in devices:
        print(d)

await main()

有了书包地址,就可以开始对它进行编程了(开机3分钟之内允许被发现和连接)。

 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
import random
from dotpack import DotPack, Animation

pack = DotPack()
# 在 microblocks 里查看 IP
address = 'B57A50BE-9FD3-1979-9185-770EA27665F6' # 书包里有一个铭牌写了书包地址
pack.connect(address)# 输入书包 address 可连接到书包
# 创建动画对象
animation = Animation()

# 生成10张雪崩图像
for x in range(10):
    # 创建一张雪崩图像
    for i in range(16):
        for j in range(16):
            if random.choice([True, False]):
                pack.set_pixel(i, j, 'white', show=False)
            else:
                pack.set_pixel(i, j, 'black', show=False)
    # 将雪崩图像添加到动画
    animation.add_frame(pack)

# 在 JupyterLab 编辑器中预览动画
# animation.show()

# 将动画上传到 dotPack (默认开机启动它)
animation.show(to_pack=pack)

由于官方主推使用 Python 对 dotPack 进行编程, dotPack 主页文档 对此有更多介绍。


todo…

Toit

LISP(ulisp)

AVR NeoPixel driver using assembler

JavaScript

我们使用 espruino ESP32

下载固件:espruino_2v13_esp32

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
esptool.py    \
        --chip esp32                                \
        --port /dev/ttyUSB0                         \
        --baud 921600                               \
        --after hard_reset write_flash              \
        -z                                          \
        --flash_mode dio                            \
        --flash_freq 40m                            \
        --flash_size detect                         \
        0x1000 bootloader.bin                       \
        0x8000 partitions_espruino.bin              \
        0x10000 espruino_esp32.bin

espruino IDE 里开始编程.

1
2
// todo: espruino 在 ESP32 下 bug 很多 :-(
require("neopixel")

DeviceScript

DeviceScript: TypeScript for Tiny IoT Devices (ESP32, RP2040, …)

Ruby

mruby-esp32

Lua

Forth

ESP32forth

Prolog

prolog-esp32

Rust

rust-esp32-example

Nim

nesper


waiting…

参考