麦克风(声音传感器)

原理简介

麦克风模块把声音(空气的振动)转换成电压信号,让 Pico 能"听见"有多吵。

  • 工作原理:声音让麦克风里的振膜振动,变成微弱电压;模块再放大后输出
  • 两种输出:
    • AO(模拟输出):声音越强电压越高,接 ADC 能读出"响度"
    • DO(数字输出):模块上比较器判断,超过灵敏度阈值就输出高/低电平
  • 本页以带 AO 的模块为主(能读强度),同时说明 DO(只能判断有没有声音)
  • 接口:AO 接 ADC(模拟输入),DO 接普通 GPIO(数字输入)

典型应用

  • 声控灯 / 声控风扇(声音一响就开)
  • 环境噪声监测(吵不吵)
  • 拍手计数器、击掌开关
  • 声音触发录音 / 拍照
  • 简易音乐节拍检测

接线图

[接线图占位,后续添加]

文字说明(具体接法见下方代码注释):

  • 模块 VCC → Pico 3V3
  • 模块 GND → Pico GND
  • 模块 AO → Pico GP26(ADC0,模拟输入,读响度)
  • 模块 DO → Pico GP14(数字输入,可选;不接也能跑基础/进阶示例)
  • 灵敏度电位器在模块上,现场用螺丝刀调

示例代码

基础示例:循环读取声音强度

# ============ 接线 ============
# 麦克风模块 VCC → Pico 3V3
# 麦克风模块 GND → Pico GND
# 麦克风模块 AO  → Pico GP26(ADC0,模拟输入)
# DO 暂时不接也能跑本示例
# =============================
from machine import ADC, Pin
import time

mic = ADC(Pin(26))              # GP26 是 ADC0

print('开始读取声音强度...')

while True:
    raw = mic.read_u16()        # 原始值 0 ~ 65535
    print('原始值:', raw)
    time.sleep_ms(100)

进阶示例:采样求峰值,判断"有没有声音"

# ============ 接线 ============
# 麦克风模块 VCC → Pico 3V3
# 麦克风模块 GND → Pico GND
# 麦克风模块 AO  → Pico GP26(ADC0)
# =============================
from machine import ADC, Pin
import time

mic = ADC(Pin(26))

# 阈值要现场实测标定!先跑基础示例看安静时/吵时的值
# 下面这个 35000 只是示例,每个人的模块、环境都不同
THRESHOLD = 35000

print('检测有没有声音...')

while True:
    # 声音是快速变化的信号,单次读数没意义,连续采一段取峰值
    peak = 0
    for _ in range(50):
        v = mic.read_u16()
        if v > peak:
            peak = v
        time.sleep_us(200)       # 采样间隔,越小越能抓住瞬间尖峰

    if peak > THRESHOLD:
        print('有声音!峰值:', peak)
    else:
        print('安静,峰值:', peak)
    time.sleep_ms(50)

应用示例:声控灯雏形(声音越大 LED 越亮)

# ============ 接线 ============
# 麦克风模块 VCC → Pico 3V3
# 麦克风模块 GND → Pico GND
# 麦克风模块 AO  → Pico GP26(ADC0)
# LED 正极 → 串联 220Ω 限流电阻 → Pico GP15
# LED 负极 → Pico GND
# (GP15 是 PWM 输出,控制亮度)
# =============================
from machine import ADC, Pin, PWM
import time

mic = ADC(Pin(26))
led = PWM(Pin(15))              # LED 接 GP15,用 PWM 调亮度
led.freq(1000)                  # PWM 频率 1kHz

print('声控灯:声音越大越亮')

while True:
    peak = 0
    for _ in range(50):
        v = mic.read_u16()
        if v > peak:
            peak = v
        time.sleep_us(200)

    # read_u16() 是 0~65535,把它映射到 LED 占空比 0~65535
    duty = peak
    led.duty_u16(duty)          # 声音越大 duty 越大,灯越亮
    time.sleep_ms(50)

注意事项

  • ADC 范围:read_u16() 返回的是 0 ~ 65535,不是 0~1023(那是 read())
  • 单次读数没意义:声音是快速变化的,要连续采样取峰值或平均值(见进阶示例)
  • 阈值要现场标定:安静环境和吵闹环境、不同模块的灵敏度都不一样,先把基础示例跑出来看数值再定 THRESHOLD
  • 电位器要调:模块上的灵敏度电位器影响 AO 输出幅度,现场边调边看
  • 供电:这类模块多为 3.3V–5V 兼容;接 Pico 的 3V3 即可,不要接 5V 脚(VBUS)以免信号超 3.3V 烧坏 GP26
  • LED 必须串限流电阻:直接把 LED 接 GPIO 会过流烧坏 LED 和引脚,一定要串 220Ω 左右电阻

常见问题

Q: 读出来的值一直不变 / 全是 0 或全是 65535? A: 检查 AO 有没有接到 GP26(ADC 脚),GP26/27/28 才是 ADC。再检查 VCC、GND 是否接好,电位器是否调死。

Q: 怎么确定阈值设多少? A: 先只跑基础示例,对着模块小声、大声各试几次,记下你想要的"有声音"对应的数值区间,再填进 THRESHOLD。

Q: 我的模块只有 DO 没有 AO 怎么办? A: 那只能判断"有没有超过阈值",不能读响度。把 DO 接 GP14(Pin(14, Pin.IN)),读到高/低电平即代表有/无声音,声控灯就无法做"越响越亮",只能做"有声就亮"。