我的第一个 TinyGo 项目:ESP32-C3 + DHT11 + SSD1306

我的第一个 TinyGo 项目:ESP32-C3 + DHT11 + SSD1306

前言

最近开始学习 TinyGo,这是我的第一个 TinyGo 嵌入式项目。作为一个 Go 语言爱好者,能用熟悉的语法来编写嵌入式程序,这种感觉非常奇妙。项目已开源在 Gitee 上:gitee.com/magic_drago...

为什么选择 TinyGo?

TinyGo 是 Go 语言的一个编译器子集,专门针对微控制器和 WebAssembly 等资源受限环境。相比 C/C++,它有这些吸引我的地方:

  • 语法熟悉 --- 如果你已经会 Go,上手几乎零成本
  • 垃圾回收 --- 不用手动管理内存,嵌入式开发也能享受 GC 的便利
  • Goroutine --- 虽然在 MCU 上用得不多,但并发模型依然可用
  • 丰富的驱动库 --- tinygo.org/x/drivers 提供了大量常见传感器的驱动

项目简介

这个项目使用 ESP32-C3 开发板,搭配 DHT11 温湿度传感器和 SSD1306 OLED 显示屏,实现了一个简单的环境监测小装置:

  • 每 2 秒读取一次 DHT11 的温度和湿度数据
  • 将温湿度及 LED 状态实时显示在 OLED 屏幕上
  • 通过按钮中断控制 LED 开关,带软件消抖

硬件连接

外设 ESP32-C3 引脚 说明
LED GPIO2 通过 330Ω 电阻接 LED 正极
按钮 GPIO3 一端接 GPIO3,另一端接 GND
DHT11 DAT GPIO4 DHT11 模块的数据引脚
OLED SDA GPIO5 I2C 数据线
OLED SCL GPIO6 I2C 时钟线

核心代码解读

1. I2C 总线与 OLED 初始化

go 复制代码
i2c.Configure(machine.I2CConfig{
    SCL:       machine.GPIO6,
    SDA:       machine.GPIO5,
    Frequency: 400_000,
})

disp = ssd1306.NewI2C(i2c)
disp.Configure(ssd1306.Config{
    Width:   128,
    Height:  64,
    Address: 0x3C,
})

SSD1306 通过 I2C 总线通信,配置为 400kHz 快速模式。128x64 分辨率的屏幕使用 0x3C 地址。

2. DHT11 传感器读取

go 复制代码
dhtSensor = dht.New(machine.GPIO4, dht.DHT11)
dhtSensor.Configure(dht.UpdatePolicy{
    UpdateTime:          2 * time.Second,
    UpdateAutomatically: true,
})

DHT11 数据手册要求最小读取间隔为 2 秒,设置 UpdateAutomatically 后调用 TemperatureFloat / HumidityFloat 会自动触发读取,非常方便。

3. 按钮中断与消抖

go 复制代码
button.SetInterrupt(machine.PinFalling, func(p machine.Pin) {
    if time.Since(lastPress) < 50*time.Millisecond {
        return
    }
    lastPress = time.Now()
    led.Set(!led.Get())
})

机械按钮按下时触点会弹跳,产生多次快速电平变化。通过记录上次触发时间,忽略 50ms 内的重复触发,实现软件消抖。

4. 超级循环模式

go 复制代码
for {
    err := dhtSensor.ReadMeasurements()
    if err != nil {
        show("DHT11 Error", "", "")
    } else {
        temp, _ := dhtSensor.TemperatureFloat(dht.C)
        hum, _ := dhtSensor.HumidityFloat()
        show(
            fmt.Sprintf("T:%.1fC", temp),
            fmt.Sprintf("H:%.1f%%", hum),
            fmt.Sprintf("LED:%v", led.Get()),
        )
    }
    time.Sleep(2 * time.Second)
}

嵌入式程序的核心结构:无限循环中不断读取传感器、处理数据、刷新显示。注意 main 函数不能退出,否则设备会重启。

踩坑记录

  1. DHT11 读取间隔 --- 刚开始频繁读取导致数据全是错误,后来才注意到数据手册要求至少间隔 2 秒
  2. OLED 地址 --- 128x64 的屏幕地址是 0x3C,128x32 是 0x3D,搞混了屏幕不会亮
  3. 按钮消抖 --- 不加消抖逻辑的话,按一次按钮 LED 会翻转多次,50ms 的消抖阈值实测效果不错
  4. main 不能退出 --- 嵌入式程序的 main 函数必须保持运行,退出后芯片会自动重启

编译与烧录

bash 复制代码
# 编译并烧录到 ESP32-C3
tinygo flash -target=esp32c3 .

# 仅编译生成固件
tinygo build -target=esp32c3 -o firmware.bin .

总结

作为第一个 TinyGo 项目,虽然功能简单,但覆盖了嵌入式开发的几个核心知识点:GPIO 控制、I2C 通信、传感器驱动、中断处理。TinyGo 的开发体验确实不错,Go 的简洁语法让嵌入式编程也变得优雅起来。

接下来打算尝试:

  • 接入 WiFi,把温湿度数据上报到服务器
  • 尝试 MQTT 协议
  • 用 Goroutine 实现更复杂的并发逻辑

如果你也对 TinyGo 感兴趣,欢迎交流!

项目地址 :gitee.com/magic_drago...

相关推荐
做萤石二次开发的哈哈6 小时前
网络音箱如何接入?音频文件夹、TTS播报、音量管控与ISAPI透传对接详解
人工智能·物联网·蓝海aiot一站式工作台·aiot开发·网络音箱·智慧广播·二次开放
花 满 楼7 小时前
HSM自学之路——阶段5安全启动专题与实践
安全·嵌入式·汽车电子·hsm·安全启动
by————组态7 小时前
Ricon组态适用领域全景解析:工业制造、能源、市政民生与智慧城市四大场景落地实践
后端·物联网·数学建模·智慧城市·能源·制造·组态
资深电气设计8 小时前
ABB AFC/AF/AX系列接触器在数据中心液冷机组中的负载适配技术
运维·物联网·创业创新·业界资讯
Jason_zhao_MR8 小时前
新一代电能数据采集终端方案
linux·人工智能·嵌入式硬件·fpga开发·嵌入式
rtu遥测终端机8 小时前
四信智慧船舶动态感知方案实现船岸一体化智能监管
物联网
星恒讯工业路由器9 小时前
工信部调整超宽带设备频段:7-9GHz为5G/6G腾频谱,工业UWB设备面临合规升级
网络·物联网·5g·无线通信·5g专网·超宽带uwb·频谱管理
HZZD_HZZD9 小时前
厂区三级计量怎么选表?互感器倍率与需量管理
大数据·物联网·腾讯云
wuyk55510 小时前
《WiFi 嵌入式物联网开发全套实战》| 第 34 章 无线抓包分析:扫描超时、关联失败、认证失败原因
物联网
wuyk5551 天前
《WiFi 嵌入式物联网开发全套实战》| 第 31 章 休眠唤醒 WiFi 断连、时间同步、网络恢复机制
网络·物联网·php