第15课 语音动感世界#

15.1 项目介绍#

在前面的教程中,已经了解过SK6812模块、智能语音模块和无源蜂鸣器的工作原理和应用。

在本项目中,使用智能语音模块来控制SK6812RGB灯模块和无源蜂鸣器,实现自动化语音控制多彩灯光及蜂鸣器发出鸣叫声与播放美妙音乐。

15.2 实验组件#

ESP32 Plus主板 *1

智能语音模块 *1

SK6812RGB灯 *1

4p线 *1

无源蜂鸣器模块 *1

3P线 *2

USB线 *1

15.3 模块接线图#

智能语音模块、无源蜂鸣器和SK6812RGB灯模块的控制引脚:

SK6812RGB灯(S引脚)

io26

无源蜂鸣器(S引脚)

io25

智能语音模块(TXD引脚)

io16

智能语音模块(RXD引脚)

io27

⚠️ 特别注意:智能家居已经组装好了,这里不需要把智能语音模块、无源蜂鸣器和SK6812RGB灯模块拆下来又重新组装和接线,这里再次提供接线图,是为了方便您编写代码!

15.4 代码流程图#

15.5 实验代码#

打开“Thonny”软件,点击“此电脑” → “D:” → “MicroPython资料” → “MicroPython_代码”。并鼠标左键双击“Project_15_voice_control_sk6812_buzzer.py”。

# 作者 : www.keyes-robot.com

from machine import Pin, PWM, UART
import neopixel
import time
import math

# 定义引脚
LED_PIN = 26
LED_COUNT = 4
BUZZER_PIN = 25
RX_PIN = 27
TX_PIN = 16

# 初始化NeoPixel
strip = neopixel.NeoPixel(Pin(LED_PIN), LED_COUNT)

# 初始化蜂鸣器
buzzer = PWM(Pin(BUZZER_PIN))
buzzer.duty(0)

# 初始化软件串口 (UART2)
uart = UART(2, baudrate=9600, rx=RX_PIN, tx=TX_PIN)

def color_wipe(color, wait):
    for i in range(len(strip)):
        strip[i] = color
        strip.write()
        time.sleep_ms(wait)

def theater_chase_rainbow(wait):
    first_pixel_hue = 0
    for a in range(30):
        for b in range(3):
            strip.fill((0, 0, 0))
            for c in range(b, len(strip), 3):
                hue = first_pixel_hue + c * 65536 // len(strip)
                rgb = hsv_to_rgb(hue / 65536.0, 1.0, 1.0)
                strip[c] = (int(rgb[0]), int(rgb[1]), int(rgb[2]))
            strip.write()
            time.sleep_ms(wait)
            first_pixel_hue += 65536 // 90

def hsv_to_rgb(h, s, v):
    if s == 0.0:
        return (v * 255, v * 255, v * 255)
    i = int(h * 6.0)
    f = (h * 6.0) - i
    p = v * (1.0 - s)
    q = v * (1.0 - s * f)
    t = v * (1.0 - s * (1.0 - f))
    i = i % 6
    if i == 0:
        return (v * 255, t * 255, p * 255)
    if i == 1:
        return (q * 255, v * 255, p * 255)
    if i == 2:
        return (p * 255, v * 255, t * 255)
    if i == 3:
        return (p * 255, q * 255, v * 255)
    if i == 4:
        return (t * 255, p * 255, v * 255)
    if i == 5:
        return (v * 255, p * 255, q * 255)

def play_tone(frequency, duration):
    if frequency == 0:
        buzzer.duty(0)
    else:
        buzzer.freq(frequency)
        buzzer.duty(512)
    time.sleep_ms(duration)
    buzzer.duty(0)

def birthday():
    tones = [
        (294, 250),  # D4
        (440, 250),  # A4
        (392, 250),  # G4
        (532, 250),  # C5
        (494, 250),  # B4
        (392, 250),  # G4
        (440, 250),  # A4
        (392, 250),   # G4
        (392, 250),  # G4
        (587, 250),  # D5
        (532, 250),  # C5  
        (392, 250),  # G4
        (784, 250), # G5
        (659, 250),  # E5
        (532, 250),  # C5  
        (494, 250),  # B4
        (440, 250),  # A4
        (698, 250),  # F5
        (659, 250),  # E5
        (532, 250),  # C5  
        (587, 250),  # D5
        (532, 500),  # C5-长时
        (0, 0),      # 关闭蜂鸣器
    ]
    for freq, dur in tones:
        play_tone(freq, dur)
        time.sleep_ms(50)

while True:
    if uart.any():
        command = uart.read(1)
        if command:
            cmd = ord(command)
            print("执行命令:", cmd) 
            
            if cmd == 11:
                birthday()
            elif cmd == 12:
                play_tone(0, 0)
            elif cmd == 13:
                color_wipe((255, 0, 0), 50)
            elif cmd == 14:
                color_wipe((0, 0, 0), 50)
            elif cmd == 15:
                color_wipe((0, 255, 0), 50)
            elif cmd == 16:
                color_wipe((0, 0, 0), 50)
            elif cmd == 17:
                color_wipe((0, 0, 255), 50)
            elif cmd == 18:
                color_wipe((0, 0, 0), 50)
            elif cmd == 36:
                theater_chase_rainbow(50)
            elif cmd == 37:
                color_wipe((0, 0, 0), 50)
            elif cmd == 38:
                play_tone(784, 250)
            elif cmd == 39:
                play_tone(0, 0)
            
            # 回声命令(可选)
            uart.write(str(cmd))

15.6 实验结果#

按照接线图接好线,将 ESP32 主控板通过Micro USB数据线与计算机相连供电,外接电源供电,然后单击按钮,示例代码开始执行。

示例代码开始执行之后,可以通过智能语音模块来控制无源蜂鸣器和SK6812RGB灯。

对着智能语音模块上的麦克风,使用唤醒词 “你好,小智” 或 “小智小智” 来唤醒智能语音模块,同时喇叭播放回复语 “有什么可以帮到您”;

智能语音模块唤醒后,对着麦克风说:“播放音乐” 等命令词时,喇叭播放对应的回复语 “已为您播放音乐”,同时蜂鸣器播放音乐;

对着麦克风说:“关闭音乐” 等命令词时,喇叭播放对应的回复语 “已为您停止音乐”,同时蜂鸣器停止播放音乐;

对着麦克风说:“打开红灯” 等命令词时,喇叭播放对应的回复语 “已为您打开红灯”,同时SK6812灯亮红色灯;

对着麦克风说:“关闭红灯” 等命令词时,喇叭播放对应的回复语 “已为您关闭红灯”,同时SK6812灯熄灭;

对着麦克风说:“打开绿灯” 等命令词时,喇叭播放对应的回复语 “已为您打开绿灯”,同时SK6812灯亮绿色灯;

对着麦克风说:“关闭绿灯” 等命令词时,喇叭播放对应的回复语 “已为您关闭绿灯”,同时SK6812灯熄灭;

对着麦克风说:“打开蓝灯” 等命令词时,喇叭播放对应的回复语 “已为您打开蓝灯”,同时SK6812灯亮蓝色灯;

对着麦克风说:“关闭蓝灯” 等命令词时,喇叭播放对应的回复语 “已为您关闭蓝灯”,同时SK6812灯熄灭;

对着麦克风说:“打开彩灯” 等命令词时,喇叭播放对应的回复语 “已为您打开彩灯”,同时SK6812灯亮彩色灯;

对着麦克风说:“关闭彩灯” 等命令词时,喇叭播放对应的回复语 “已为您关闭彩灯”,同时SK6812灯熄灭;

对着麦克风说:“打开蜂鸣器” 或 “蜂鸣器开始鸣叫”等命令词时,喇叭播放对应的回复语 “已打开蜂鸣器”,同时蜂鸣器开始鸣叫;

对着麦克风说:“关闭蜂鸣器” 或 “蜂鸣器停止鸣叫” 等命令词时,喇叭播放对应的回复语 “已关闭蜂鸣器”,同时蜂鸣器停止鸣叫。

Img

单击“停止/启动后端进程”退出程序。