国庆节祝愿:祖国繁荣昌盛国泰民安福寿绵长

2026-10-02151
精华项目
AI 快速预览详细 收起
本文介绍了一个使用行空板K10制作的国庆升旗仪式项目。该项目通过A/B按键控制升旗过程,RGB灯渐变和音效增强体验。文章详细介绍了项目的背景、功能、硬件清单、程序编写方法以及效果查看。此外,还提供了后续可改进的方向,如加入国歌、国旗飘动等。这个项目适用于STEM教育场景,能够激发孩子的创造力和爱国情怀。

行空板 K10为祖国母亲庆祝生日

一、项目背景

1.1 需求来源

国庆假期中段,需要在行空板 K10 上做一个与国庆主题相关、能在课堂上当场演示的作品。这次想要一个有仪式感、能讲出故事的东西——于是选了「天安门升旗仪式」。

选择的理由:

候选方案 评估
天安门升旗仪式(选定) 仪式感强,画面是静态为主
国庆烟花秀 最炫,但一帧画上百个粒子根本跑不动
国庆知识抢答 最快出成品,但几乎全是文字,交互体验一般

1.2 行空板K10介绍

行空板K10是一款专为信息科技课程中的编程学习、物联网及AI项目教学需求而开发的学习板。集摄像头、LCD彩屏、麦克风、扬声器、WiFi蓝牙模块、RGB指示灯及多种传感器和扩展接口于一体,无需额外设备即可实现传感器控制、物联网应用、图像检测、语音识别、语音合成等AI项目。

行空板 K10 集成了摄像头、LCD 彩屏、麦克风、扬声器、WiFi、蓝牙、RGB 指示灯及多种传感器​。在教学过程中,无需额外连接其他设备,便可轻松实现传感器控制、物联网应用以及人脸识别、语音识别、语音合成等 AI 项目。
只是屏幕不支持触摸,最简输入只能用两个键解决,后期我们可以使用语音等高科技形式。


二、功能介绍

2.1 玩法

阶段 画面 行为
待机 清晨的天安门广场:朝霞天空、金色朝阳、左侧天安门城楼、中央旗杆,国旗停在旗杆底部 灯光按模式呼吸/流水,底部提示条显示操作
升旗 国旗匀速上升 每 25% 一声鼓点;3 颗 RGB 由暗红渐亮到金红;底部显示百分比
礼成 屏幕中部出现「祝伟大祖国生日快乐」「1949 - 2026 国庆快乐」+ 星光 礼成号角 + RGB 金红快闪;

2.2 操作方式

操作 功能
A 短按 开始升旗;礼成后再按一次=再来一次
B 短按 循环切换灯光模式:关 → 常亮 → 呼吸 → 流水
B 长按(> 0.62 s) 音效开 / 关
A+B 同按 1 秒 回到待机(国旗降回底部,祝福语清除)

升旗过程中 B 短按不生效(避免在仪式中途误触改灯光),这是刻意的:main() 里用 elif state != ST_RAISE 挡掉。

2.4 状态机

+----------------------------+
        |                            |
        v        A 短按               |  pct >= 100
   +---------+  -------->  +---------+  -------->  +---------+
   |  ST_IDLE|             | ST_RAISE|             | ST_DONE |
   +---------+  <--------  +---------+  <--------  +---------+
        ^          A+B 1s                  A 短按
        |                                  (再来一次)
        +--------------------------------------+

三、硬件清单

3.1 必需件

名称 规格 用途
行空板 K10 ESP32-S3,2.8" 240×320 ILI9341 主控 + 显示
USB Type-C 数据线 供电 + 下载 —
电脑 + Thonny(或 mpremote) 上传 main.py 与 wav —

3.2 用到的板载资源

资源 接口 本项目中的用途
屏幕 screen.init(dir=2) → 竖屏 240×320 全部画面
A / B 按键 button(button.a) / button(button.b) 升旗、灯光、音效、复位
3 颗 RGB 灯 rgb.write(i, r, g, b) 升旗渐变、礼成快闪、4 种灯光模式
扬声器 speaker.play_sys_music("xxx.wav") 号角、鼓点、礼成音
Flash 文件系统 open() / os.listdir() flag_cfg.txt 配置持久化


四、程序编写

赋值

把"会动的东西"和"不动的东西"分开,这是整个程序最关键的一条设计约束:

POLE_X, POLE_W = 138, 3         # 旗杆
FLAG_X = 142                    # 国旗左边缘(紧贴旗杆右侧)
FLAG_W, FLAG_H = 90, 60         # 3:2
FLAG_Y_TOP = 48                 # 升到顶时的 y
FLAG_Y_BOT = 240                # 起始 y(旗底 300, 正好在地平线上)

静物区域

静物 占位 与国旗区重叠?
人民英雄纪念碑(近景主体) x ∈ [26, 114],y ∈ [52, 300] 否
天安门城楼(远景剪影) x ∈ [4, 132],y ∈ [196, 272] 否
朝阳 + 光晕 x ∈ [4, 36],y ∈ [48, 80] 否
标题 / 副标题 y ∈ [6, 40] 否(在旗顶 y=48 之上)

绘制天空

def paint_sky(x, y, w, h):
    """只重绘与给定矩形相交的天空色带 —— 擦除国旗就靠它。"""
    b0 = y // BAND_H
    b1 = (y + h - 1) // BAND_H
    for b in range(b0, b1 + 1):
        ty0 = b * BAND_H
        ty1 = ty0 + BAND_H
        cy0 = ty0 if ty0 > y else y
        cy1 = ty1 if ty1 < y + h else y + h
        fill(x, cy0, w, cy1 - cy0, SKY_BANDS[b])

五角星画法

def star_offsets(R):
    out = []
    for i in range(10):
        ang = -1.5707963 + i * 0.62831853       # -90° + i*36°
        r = R if i % 2 == 0 else R * 0.382      # 标准五角星内外半径比
        out.append((int(round(r * math.cos(ang))), int(round(r * math.sin(ang)))))
    return out

改进后的程序

STAR_IDX5 = (0, 4, 8, 2, 6)      # 一笔画顺序: 跳过一个外顶点

def draw_star(cx, cy, offs, color):
    n = len(STAR_IDX5)
    for i in range(n):
        x1, y1 = offs[STAR_IDX5[i]]
        x2, y2 = offs[STAR_IDX5[(i + 1) % n]]
        screen.draw_line(cx + x1, cy + y1, cx + x2, cy + y2, color)

画四颗五角星

STAR_R_SMALL = 4                # 标准应为 3, 放大到 4 让星形一眼可辨

for sx, sy in STAR_SMALL:                            
    px = FLAG_X + sx
    py = y + sy
    draw_star(px, py, STAR_S_OFF, C_STAR)
    screen.draw_circle(x=px, y=py, r=1, bcolor=C_STAR, fcolor=C_STAR)

升旗循环

pct = el * 100 // RAISE_MS
ny  = FLAG_Y_BOT - (FLAG_Y_BOT - FLAG_Y_TOP) * pct // 100

原本写成 p = el / float(RAISE_MS) 这种浮点写法,每帧都要分配 float 对象,反复分配会招来 GC。改成整数除法后,长帧从"偶发 367 ms"降到基本不出现。

灯光

升旗中按高度由暗红转金红(整数运算,避免 GC):

if pct >= 0:
    v = 40 + 200 * pct // 100
    rgb_all(v, v * 35 * pct // 10000, 0)
    return

其余状态按 4 种模式走:关 / 常亮(暗红)/ 呼吸(正弦)/ 流水(3 颗轮流亮)。礼成时 light_flash() 金红交替快闪,每 160 ms 切一次。

主循环与按键边沿

while True:
    now = time.ticks_ms()
    a = bt_a.status()
    b = bt_b.status()

    if a and not last_a:
        a_down_ms = now
    if b and not last_b:
        b_down_ms = now
    if a and b:
        if both_ms == 0:
            both_ms = now
    else:
        both_ms = 0

    if not a and last_a:                       # A 松手: 短按 = 升旗
        if state != ST_RAISE and time.ticks_diff(now, a_down_ms) < LONG_MS:
            start_raise(now)
    if not b and last_b:                       # B 松手: 长按 = 音效, 短按 = 灯光
        dur = time.ticks_diff(now, b_down_ms)
        if dur >= LONG_MS:
            snd_on = not snd_on
            save_cfg()
            last_foot = -1
        elif state != ST_RAISE:
            light_mode = (light_mode + 1) % 4
            save_cfg()
            last_foot = -1
    if a and b and both_ms and time.ticks_diff(now, both_ms) >= BOTH_MS:
        to_idle()
        both_ms = 0

    last_a = a
    last_b = b

    if state == ST_RAISE:
        tick_raise(now)
    elif state == ST_DONE:
        tick_done(now)
    else:
        tick_idle(now)

    time.sleep_ms(LOOP_MS)                     # 10 ms 轮询

五、效果查看

六、后续可改进方向

方向 做法 收益
加国歌 传一个完整的 anthem.wav(已留接口) 仪式感拉满
国旗飘动 在旗面右侧加正弦摆动的短竖线 更生动,但每帧多几次 draw_line
加日期倒计时 用 time + 手动设定日期,显示"距国庆还有 N 天" 需先校时

最后祝愿祖国:

繁荣昌盛、国泰民安、福寿绵长

创作许可协议

本项目采用 CC BY(署名) 进行许可。

评论(1)
Lumen微光

我建议可以把五角星的绘图优化一下,小星星的角对准大星星

- 没有更多了 -