编写一个给M5CardputerADV用的DS18B20测温程序,重点优化测量咖啡冲煮温度区间,要有...

Creado el: 18 de agosto de 2026

Respondido usando GPT-5.6 Thinking por Chat01

Pregunta

编写一个给M5CardputerADV用的DS18B20测温程序,重点优化测量咖啡冲煮温度区间,要有ui显示温度。
DS18B20我准备通过压线端子加电阻转接模块转成接地供电和数据三个gpio引脚接入CardputerADV,注意避开所有硬件占用保留引脚,避免例如选择到与SD卡引脚相同的引脚,造成该引脚信号无限重复发送。
M5CardputerADV的所有规格与库的API用法通通自己上网查清楚,用M5CardputerADV官方打包的https://github.com/m5stack/M5Cardputer库,不要用esp32s3或arduion这种底层,尽量让代码简短精简。

Pensamiento

Searched 1 website

Worked for 3m 52s

Respuesta

可以。按我查到的 Cardputer ADV 官方 PinMap、当前 M5Cardputer 源码/API、DS18B20 数据手册,我建议把方案直接定成:

DS18B20 数据脚用 Cardputer ADV 的 HY2.0-4P 上的 G2(黄色线),G1 留空。这样完全避开 microSD、LCD、键盘、IMU、音频和红外等板载资源。ADV 官方明确标出 microSD 为 G12=CS、G14=MOSI、G40=CLK、G39=MISO;LCD 用 G33–G38;键盘用 G8/G9/G11;音频还用 G8/G9/G41/G42/G43/G46;IMU 用 G8/G9;IR 用 G44;电池 ADC 用 G10。HY2.0 则是 GND / 5V / G2 / G1,所以 G2 是这里最干净的选择。尤其不要选 G40——它就是 SD 时钟脚,出现你说的那种持续时钟/重复信号完全有可能。(M5Stack Docs)

接线先注意一个非常重要的问题

Cardputer ADV 的 HY2.0 红线是 5V,不是 3.3V。DS18B20 本身允许 3.0–5.5V 供电,并典型使用约 4.7kΩ 的 1-Wire 上拉;但 ESP32-S3 的普通 GPIO 是 3.3V 电气域,其高电平输入规格上限为 VDD + 0.3V,也就是大约 3.6V。因此,不能把你的 4.7k 上拉电阻直接接到 HY2.0 的 5V 上,再把 DQ 直接接 G2。(Analog Devices)

最稳妥的三线 Cardputer 侧接法是:

Cardputer ADV HY2.0转接模块DS18B20
黑线 GNDGNDGND
红线 5V降压/稳压至 3.3VVDD
黄线 G2DQ,且 4.7kΩ 上拉到转接后的 3.3VDQ
白线 G1不接

也就是说,你的“压线端子+电阻模块”最好顺手加一个很小的 3.3V 稳压。这样 Cardputer 外部仍然只有 GND / 5V / G2 三根线。如果你买的是那种“三针 DS18B20 模块”,板上的 4.7k 往往直接从 DATA 拉到 VCC;这类模块如果 VCC 接 Cardputer 的 5V,DATA 也会被拉向 5V,不要直接这么接

为什么程序用 11-bit,而不是无脑 12-bit

这个对咖啡测温很重要。DS18B20 的 12-bit 分辨率虽然达到 0.0625°C,但转换最长要 750ms;11-bit 是 0.125°C / 375ms。更关键的是,DS18B20 的 ±0.5°C 精度只保证到 +85°C,而 -30~+100°C 的规格是 ±1°C,也就是说咖啡常见的 90~96°C 区间本来就不是 ±0.5°C 区间。12-bit 在这里主要增加数字位数,并不会把实际准确度变成 ±0.06°C。(Analog Devices)

因此我这里选 11-bit + 380ms 非阻塞转换周期 + 轻度快速滤波 + 一位小数显示。大约 2.6 次/秒的更新对于金属探针 DS18B20 已经足够,因为实际探针外壳和灌封材料的热惯性通常比 ADC 转换慢得多。DallasTemperature 当前 API 也直接提供了 setResolution()setWaitForConversion()requestTemperatures()getTempCByIndex(),所以没必要自己写 GPIO 时序。(GitHub)

程序

下面代码的设备/UI 部分全部走官方 M5Cardputer / 它所包含的 M5Unified API。没有 pinMode()digitalWrite()、裸 ESP32-S3 GPIO、寄存器或 ESP-IDF GPIO 调用;计时也用 M5.millis() / M5.delay()。当前官方 M5Cardputer 仓库明确写明同时支持 M5Cardputer 和 M5Cardputer-ADV,并公开 begin()Displayupdate() 等接口。(GitHub)

cpp
#include <M5Cardputer.h> #include <OneWire.h> #include <DallasTemperature.h> // Cardputer ADV HY2.0: // Black=GND, Red=5V, Yellow=G2, White=G1 constexpr uint8_t DS_PIN = 2; // Yellow / G2 // Coffee-focused UI range constexpr float BREW_LOW = 90.5f; constexpr float BREW_HIGH = 96.0f; constexpr float SCALE_LOW = 85.0f; constexpr float SCALE_HIGH = 100.0f; // Calibrate against a trusted reference around brewing temperature. constexpr float TEMP_OFFSET = 0.0f; // 1.0 = raw; 0.65 gives light smoothing without much lag. constexpr float FILTER = 0.65f; // DS18B20 11-bit max conversion time = 375 ms. constexpr uint32_t CONVERSION_MS = 380; OneWire oneWire(DS_PIN); DallasTemperature ds(&oneWire); uint32_t conversionStarted; float shownTemp = 0; bool firstReading = true; bool errorShown = false; constexpr int BAR_X = 12; constexpr int BAR_Y = 100; constexpr int BAR_W = 216; int tempX(float t) { if (t < SCALE_LOW) t = SCALE_LOW; if (t > SCALE_HIGH) t = SCALE_HIGH; return BAR_X + (int)((t - SCALE_LOW) * BAR_W / (SCALE_HIGH - SCALE_LOW)); } void drawBar(float t, bool marker) { auto& d = M5Cardputer.Display; int lo = tempX(BREW_LOW); int hi = tempX(BREW_HIGH); d.fillRect(BAR_X, BAR_Y - 3, BAR_W, 17, TFT_BLACK); d.fillRect(BAR_X, BAR_Y, BAR_W, 11, TFT_DARKGREY); d.fillRect(lo, BAR_Y, hi - lo, 11, TFT_GREEN); if (marker) { int x = tempX(t); d.fillRect(x - 1, BAR_Y - 3, 3, 17, TFT_WHITE); } } void drawFrame() { auto& d = M5Cardputer.Display; d.setRotation(1); d.fillScreen(TFT_BLACK); d.setTextDatum(middle_center); d.setTextColor(TFT_WHITE, TFT_BLACK); d.setTextSize(1); d.drawString("COFFEE WATER / DS18B20", 120, 9); drawBar(0, false); d.drawString("85", 20, 124); d.drawString("90.5", tempX(BREW_LOW), 124); d.drawString("96", tempX(BREW_HIGH), 124); d.drawString("100", 220, 124); } void drawTemperature(float t) { auto& d = M5Cardputer.Display; uint16_t color; const char* state; if (t < BREW_LOW) { color = TFT_CYAN; state = "BELOW BREW RANGE"; } else if (t <= BREW_HIGH) { color = TFT_GREEN; state = "BREW RANGE"; } else { color = TFT_RED; state = "ABOVE BREW RANGE"; } d.fillRect(0, 20, 240, 77, TFT_BLACK); d.setTextDatum(middle_center); char text[16]; snprintf(text, sizeof(text), "%.1f C", t); d.setTextColor(color, TFT_BLACK); d.setTextSize(4); d.drawString(text, 120, 54); d.setTextSize(1); d.drawString(state, 120, 86); drawBar(t, true); } void drawError() { auto& d = M5Cardputer.Display; d.fillRect(0, 20, 240, 77, TFT_BLACK); d.setTextDatum(middle_center); d.setTextColor(TFT_RED, TFT_BLACK); d.setTextSize(2); d.drawString("NO SENSOR", 120, 50); d.setTextColor(TFT_WHITE, TFT_BLACK); d.setTextSize(1); d.drawString("G2 / 4.7k -> 3.3V", 120, 78); drawBar(0, false); } void setup() { // Keyboard is unused, so don't initialize its handler. M5Cardputer.begin(false); drawFrame(); ds.begin(); ds.setResolution(11); ds.setWaitForConversion(false); ds.requestTemperatures(); conversionStarted = M5.millis(); } void loop() { M5Cardputer.update(); if (M5.millis() - conversionStarted < CONVERSION_MS) { M5.delay(5); return; } float t = ds.getTempCByIndex(0); if (t == DEVICE_DISCONNECTED_C) { firstReading = true; if (!errorShown) { drawError(); errorShown = true; } // Allows automatic recovery after unplug/replug. ds.begin(); ds.setResolution(11); } else { errorShown = false; t += TEMP_OFFSET; if (firstReading) { shownTemp = t; firstReading = false; } else { shownTemp += FILTER * (t - shownTemp); } drawTemperature(shownTemp); } ds.requestTemperatures(); conversionStarted = M5.millis(); }

UI 会把 85~100°C 集中铺满 240×135 屏幕,而不是把 DS18B20 的整个 -55~125°C 范围浪费在咖啡场景上;90.5~96°C 区域会显示为绿色,温度低于目标显示青色,高于目标显示红色,并有实时位置指示条。官方 M5Cardputer 示例本身也是通过 M5Cardputer.DisplaysetRotation()setTextSize()setTextDatum()drawString()、图形绘制等 M5GFX API 完成 UI。(GitHub)

为什么默认目标是 90.5~96°C

这里不是把它说成所有咖啡的“唯一正确温度”。SCA 资料中引用的传统 SCAA espresso 定义使用 195–205°F,即约 90.5–96.1°C;SCA 关于滴滤咖啡的研究文章则提到行业长期常以约 93°C 为参考,同时也指出并不存在一个对所有咖啡都绝对最佳的单一冲煮温区。所以我把它作为 UI 默认观察窗口,而不是硬编码成“必须合格”的标准。改代码顶部的 BREW_LOW / BREW_HIGH 就可以适配浅烘、深烘、手冲或意式。(Specialty Coffee Association)

Arduino IDE 需要的库

M5Stack 官方目前对 Cardputer 和 Cardputer ADV 使用同一套快速开始流程:Board Manager 选择 M5Cardputer,安装官方 M5Cardputer 驱动库及其依赖。官方 M5Cardputer 本身没有 DS18B20/1-Wire 驱动,因此传感器侧再安装 OneWire(Paul Stoffregen)DallasTemperature(Miles Burton) 即可;DallasTemperature 自己的说明也将 OneWire 列为所需依赖。(M5Stack Docs)

这套代码刻意没有用 Arduino 的 delay()/millis() 或裸 GPIO;M5Cardputer.h 本身包含 M5Unified,而 M5Unified 当前提供 M5.millis()M5.delay(),因此应用层仍保持在 M5Stack 官方抽象里。(GitHub)

最后一个实际测温建议:TEMP_OFFSET 最好在约 90~95°C 附近拿一支可信参考温度计做一次单点修正。因为 DS18B20 在这个区间的数据手册误差本身允许到约 ±1°C,而且不锈钢防水探头的热响应延迟也不是提高到 12-bit 就能解决的。程序只显示一位小数就是为了避免制造“93.4375°C 很精准”的假象。(Analog Devices)

Compartir este Q&A