swtman 发表于 2025-8-11 22:37

温度测不准?读数据麻烦?来一起从零手搓高精度无线人体温度仪吧

本帖最后由 swtman 于 2025-9-15 13:44 编辑

<p><strong>高精度无线人体温度仪</strong></p>
<h1>1. <strong>前言</strong></h1>
<p>手中持有一款瑞萨的开发板,已经吃灰很久了。关于瑞萨开发板的使用也忘记了好多,为了发挥一下开发板的余热,同时也重新熟悉一下瑞萨开发板的使用和开发过程。因此想基于这个开发板做一个小而实用的项目。一个高精度无线温度仪由此诞生了。</p>
<p>项目目标:</p>
<p>1-精度高,小于0.1度;</p>
<p>2-带有显示屏,方便及时查看;</p>
<p>3-最重要的是支持蓝牙传输,支持BLE和SPP,既可以连接手机,也可以连接电脑。</p>
<h1>2. <strong>最终效果图</strong></h1>
<p>从无数的坑里终于爬出来了,最终完成目标,实现最终效果如下:</p>
<p><img src="高精度无线人体温度仪.files/高精度无线人体温度仪233.png" alt="" /></p>
<p>图 1 项目验证实物图</p>
<p>后续手机端,若是能做成更好的APP适配,效果会更好。硬件方面可以集成一个小盒子,会更方便收纳。</p>
<h1>3. <strong>系统硬件设计</strong></h1>
<p>本项目需要使用一些外设和模块,因此需要进行硬件设计。</p>
<h2>3.1. <strong>系统整体设计</strong></h2>
<p>主控采用RA-Eco-RA4M2-100PIN-V1.0开发板,通过IIC采集温度传感器数据,然后通过OLED显示屏显示计算的人体温度,并通过无线模块将数据发送给电脑或者手机等终端。开发通过LED显示系统正常运行。</p>
<p><img src="高精度无线人体温度仪.files/高精度无线人体温度仪508.png" alt="" /></p>
<p>图 2 整体硬件架构图</p>
<h2>3.2. <strong>RA4M2开发板</strong></h2>
<p>RA-Eco-RA4M2-100PIN-V1.0是一款基于100MHz Arm® Cortex®-M33内核架构的核心板,主控芯片为R7FA4M2AD3CFP。 RA4M2 32 位微控制器 (MCU) 产品群使用支持 TrustZone 的高性能 Arm® Cortex®-M33 内核。 与片内的 Secure Crypto Engine (SCE) 配合使用,可实现安全芯片的功能。 RA4M2 采用高效的 40nm 工艺,由灵活配置软件包 (FSP) 这个开放且灵活的生态系统概念提供支持,FSP 基于 FREERTOS 构建,并能够进行扩展,以使用其他实时操作系统 (RTOS) 和中间件。 RA4M2 适用于物联网应用的需求, 如多样化的通信功能、面向未来应用的安全功能、大容量嵌入式 RAM 和较低的运行功耗(从闪存运行 CoreMark® 算法时功耗低至 81µA/MHz)。</p>
<p>以上是官方的介绍,这个开发板的相关接口和资源介绍如下:</p>
<p>1个复位按键,2个用户按键,2个触摸按键,3个LED,2个PMOD接口,板载USB转TTL模块,可用于串口通信和烧录,板载SWD接口,方便用户调试与下载,支持 TrustZone 的 100MHz Arm Cortex-M33安全芯片的功能,512kB 闪存、64kB SRAM(支持奇偶校验)以及 64kB ECC SRAM,8KB 数据闪存,提供与 EEPROM 类似的数据存储功能,1kB 休眠用 SRAM,电容式触摸传感单元 (CTSU),全速 USB 2.0,支持主机模式和设备模式,CAN 2.0B,四线 SPI,SCI(UART、简单 SPI、简单 I2C),独立SPI/I2C 多主接口,SDHI 和 MMC。</p>
<p>本项目只是使用部分接口和资源。</p>
<h2>3.3. <strong>OLED显示屏</strong></h2>
<p>0.96寸OLED显示屏窄白光IIC接口,屏幕分辨率为128X64。这个屏幕从立创商城购买来。链接如下:</p>
<p>https://item.szlcsc.com/5960631.html?spm=sc.ols.it2-1___sc.hm.hd.dd&amp;lcsc_vid=TgJXAgVTFgdaUVFeQVZaBAFfFAJbU11e**MUV0FRlQxVlNTQlBdX1xQQFRaUDtW</p>
<p>相关参数如下:</p>
<p><img src="高精度无线人体温度仪.files/高精度无线人体温度仪1676.png" alt="" /></p>
<p>图 3 OLED显示屏采购</p>
<h2>3.4. <strong>温度传感器</strong></h2>
<p>采用敏源的M1820ZT5,该传感器具有±0.1℃精度、16bitADC、超低功耗、1-wire数字接口。是一款高精度温度传感芯片。在立创商城上购买,链接如下:</p>
<p>https://item.szlcsc.com/5750395.html?spm=sc.ols.it0-1___sc.hm.hd.dd&amp;lcsc_vid=TgJXAgVTFgdaUVFeQVZaBAFfFAJbU11e**MUV0FRlQxVlNTQlBdX1xQQFRaUDtW</p>
<p>该高精度数字温度探头,探头直径5MM,线长1米,内部芯片型号M1820Z,最高测温精度±0.1℃@0<del>+50℃,1-Wire协议数字输出,16bit ADC 0.004℃分辨率,10.5ms快速测温,1.8V</del>5.5V宽电压供电,工作温度范围-20℃~+85℃(芯片工作温度范围-70℃~+150℃)。选择这款的原因就是精度很高啊。测量也方便哦。</p>
<p><img src="高精度无线人体温度仪.files/高精度无线人体温度仪2274.png" alt="" /></p>
<p>图 4 M1820ZT5温度传感器</p>
<h2>3.5. <strong>无线模块</strong></h2>
<p>基于KT6368的蓝牙模块,支持SPP和BLE双模。不仅可以可以连接手机,也可以连接电脑。该模块板载PCB天线。通过串口控制收发数据。供电:3.3V。该模块采用立创开源的硬件制作,相关开源链接如下:</p>
<p>https://oshwhub.com/swtblue/kt86368akt6328a-bluetooth-module</p>
<p>具体实物如下:</p>
<p><img src="高精度无线人体温度仪.files/高精度无线人体温度仪2565.png" alt="" /></p>
<p>图 5 无线模块</p>
<h2>3.6. <strong>LED灯</strong></h2>
<p>这里直接使用开发板上的3个LED灯,不再详述,相关原理图如下图所示:</p>
<p><img src="高精度无线人体温度仪.files/高精度无线人体温度仪2637.png" alt="" /></p>
<p>图 6 LED控制IO</p>
<p>需要对相关GPIO进行配置。</p>
<h1>4. <strong>系统软件设计</strong></h1>
<p>通过RASC进行初始参数配置,基于keil MDK平台使用C语言进行编码。</p>
<h2>4.1. <strong>OLED的IIC配置与关键代码实现</strong></h2>
<p>OLED使用的IIC的IO分别是SDA:P408、SCL:P409。为了屏幕刷新的更快,这里配置速度为FAST-MODE。大约400KBPS。需要注意选择IIC的通道,SLAVE的地址:0x3c,并命名好回调函数。具体配置如下图所示:</p>
<p><img src="高精度无线人体温度仪.files/高精度无线人体温度仪2868.png" alt="" /></p>
<p>图 7 OLED的IIC配置</p>
<p>回调函数实现如下:</p>
<p>i2c_master_event_t i2c_event = I2C_MASTER_EVENT_ABORTED;</p>
<p>void sci_i2c_master_callback(i2c_master_callback_args_t *p_args)</p>
<p>{</p>
<pre><code>i2c\_event = I2C\_MASTER\_EVENT\_ABORTED;

if (NULL != p\_args)

{

    /\* capture callback event for validating the i2c transfer event\*/

    i2c\_event = p\_args-&gt;event;

}
</code></pre>
<p>}</p>
<p>inttimeout_ms = 100;</p>
<p>当然这里还有屏幕的驱动代码等,由于篇幅所限,不再详述。该屏幕的使用属于常规操作。具体可以查看工程源码。</p>
<p>在这里需要注意一下汉字取模,我采用的是在线进行汉字取模。网站链接如下:</p>
<p>https://www.23bei.com/tool/216.html</p>
<p>我需要使用的汉字是:高精度无线人体温度仪。通过在线取模,参数配置如下图所示:</p>
<p><img src="高精度无线人体温度仪.files/高精度无线人体温度仪3466.png" alt="" /></p>
<p>图 8汉字在线取模配置与生成</p>
<h2>4.2. <strong>温度传感器的IO配置与关键代码实现</strong></h2>
<p>该传感器单线通信,因此只需要一个IO:P115,该管脚需要外部4.7K的电阻3.3V进行上拉。否则通信会有问题。管脚P115的软件配件如下图所示:</p>
<p><img src="高精度无线人体温度仪.files/高精度无线人体温度仪3595.png" alt="" /></p>
<p>图 9温度传感器通信IO</p>
<p>该传感器的驱动代码官方已经写好,只需要对IO和延时程序重新移植即可。</p>
<p>相关需要自行配置和修改的函数如下:</p>
<p>/<em><strong><strong><strong><strong>用户可自行配置us级延时</strong></strong></strong></strong></em>***/</p>
<p>#define ow_Delay_us(N) R_BSP_SoftwareDelay(N, BSP_DELAY_UNITS_MICROSECONDS)</p>
<p>#define DELAY_Ms(N) R_BSP_SoftwareDelay(N, BSP_DELAY_UNITS_MILLISECONDS)</p>
<p>#define ow_DQ_set()    { R_IOPORT_PinWrite(&amp;g_ioport_ctrl, DQ_PIN,BSP_IO_LEVEL_HIGH); }</p>
<p>#define ow_DQ_reset() { R_IOPORT_PinWrite(&amp;g_ioport_ctrl, DQ_PIN,BSP_IO_LEVEL_LOW);}</p>
<p>uint8_t ow_DQ_get(void)</p>
<p>{</p>
<p>bsp_io_level_t x=0;</p>
<p>if(R_IOPORT_PinRead(&amp;g_ioport_ctrl,DQ_PIN,&amp;x)==FSP_SUCCESS){</p>
<p>return x;</p>
<p>}</p>
<p>return 1;</p>
<p>}</p>
<p>void OW_Init(void)</p>
<p>{</p>
<p>ow_DQ_set();</p>
<p>}</p>
<h2>4.3. <strong>LED的GPIO配置与关键代码实现</strong></h2>
<p>这里需要配置三个IO分别是P405、P404、P002分别对应LED1、LED2、LED3。配置起来非常简单,将设置为输出即可,配置分别如下图所示:</p>
<p><img src="高精度无线人体温度仪.files/高精度无线人体温度仪4320.png" alt="" /></p>
<p><img src="高精度无线人体温度仪.files/高精度无线人体温度仪4322.png" alt="" /></p>
<p><img src="高精度无线人体温度仪.files/高精度无线人体温度仪4324.png" alt="" /></p>
<p>图 10 LED控制IO配置</p>
<p>具体代码实现控制LED亮灭非常简单,如下所示:</p>
<pre><code>       R\_BSP\_SoftwareDelay(250, BSP\_DELAY\_UNITS\_MILLISECONDS); // NOLINT

       R\_IOPORT\_PinWrite(&amp;g\_ioport\_ctrl, LED1, BSP\_IO\_LEVEL\_LOW);

       R\_IOPORT\_PinWrite(&amp;g\_ioport\_ctrl, LED2, BSP\_IO\_LEVEL\_HIGH);

       R\_BSP\_SoftwareDelay(250, BSP\_DELAY\_UNITS\_MILLISECONDS); // NOLINT

       R\_IOPORT\_PinWrite(&amp;g\_ioport\_ctrl, LED1, BSP\_IO\_LEVEL\_HIGH);

       R\_IOPORT\_PinWrite(&amp;g\_ioport\_ctrl, LED2, BSP\_IO\_LEVEL\_LOW);
</code></pre>
<h2>4.4. <strong>无线模块的UART接口配置与关键代码实现</strong></h2>
<p>无线蓝牙模块的接口为串口,因此需要使用1个UART。相关配置如下:</p>
<p><img src="高精度无线人体温度仪.files/高精度无线人体温度仪4877.png" alt="" /></p>
<p>图 11 无线模块UART通信接口配置</p>
<p>相关的回调函数需要自己进行实现,相关代码如下:</p>
<p>fsp_err_t err = FSP_SUCCESS;</p>
<p>unsigned char send_buff;</p>
<p>volatile bool uart_send_complete_flag = false;</p>
<p>void g_uart9_callback (uart_callback_args_t * p_args)</p>
<p>{</p>
<pre><code>if(p\_args-&gt;event == UART\_EVENT\_TX\_COMPLETE)

{

    uart\_send\_complete\_flag = true;

}
</code></pre>
<p>}</p>
<p>为了方便调试,和打印相关信息。这里对printf函数进行了重定向,相关代码如下所示:</p>
<p>/* 重定向 printf 输出 */</p>
<p>#if defined __GNUC__ &amp;&amp; !defined __clang__</p>
<p>int _write(int fd, char *pBuffer, int size); //防止编译警告</p>
<p>int _write(int fd, char *pBuffer, int size)</p>
<p>{</p>
<p>(void)fd;</p>
<p>R_SCI_UART_Write(&amp;g_uart4_ctrl, (uint8_t *)pBuffer, (uint32_t)size);</p>
<p>while(uart_send_complete_flag == false);</p>
<p>uart_send_complete_flag = false;</p>
<p>return size;</p>
<p>}</p>
<p>#else</p>
<p>int fputc(int ch, FILE *f)</p>
<p>{</p>
<p>(void)f;</p>
<p>R_SCI_UART_Write(&amp;g_uart9_ctrl, (uint8_t *)&amp;ch, 1);</p>
<p>while(uart_send_complete_flag == false);</p>
<p>uart_send_complete_flag = false;</p>
<p>return ch;</p>
<p>}</p>
<p>#endif</p>
<h2>4.5. <strong>SWD调试与下载接口配置</strong></h2>
<p>由于我手头上有j-link调试器,所以配置SWD接口,不仅能适配我的调试器,还可以节省IO。具体配置如下图所示:</p>
<p><img src="高精度无线人体温度仪.files/高精度无线人体温度仪5873.png" alt="" /></p>
<p>图 12 SWD调试下载接口配置</p>
<h2>4.6. <strong>主程序设计</strong></h2>
<p>由于在RASC中已经配置了相关的外设,这里只需要调用即可。因此主程序实现如下:</p>
<p>/*******************************************************************************************************************//**</p>
<p>* main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used.This function</p>
<p>* is called by main() when no RTOS is used.</p>
<p>**********************************************************************************************************************/</p>
<p>void hal_entry(void)</p>
<p>{</p>
<pre><code>/\* TODO: add your own code here \*/
</code></pre>
<p>float T=0;</p>
<p>unsigned char str={0};</p>
<p>err = R_SCI_UART_Open(&amp;g_uart9_ctrl, &amp;g_uart9_cfg);</p>
<pre><code>assert(FSP\_SUCCESS == err);

    /\* IIC初始化*/

    err = R\_SCI\_I2C\_Open(&amp;g\_i2c0\_ctrl, &amp;g\_i2c0\_cfg);

    assert(FSP\_SUCCESS == err);

    WriteCmd();//OLED初始化

    OLED\_Clear();//清屏
</code></pre>
<p>//高精度无线人体温仪</p>
<pre><code>    OLED\_ShowCHinese(0,1,0);//高

    OLED\_ShowCHinese(16,1,1);//精

    OLED\_ShowCHinese(32,1,2);//度

    OLED\_ShowCHinese(48,1,3);//无

    OLED\_ShowCHinese(64,1,4);//线

    OLED\_ShowCHinese(80,1,7);//温

    OLED\_ShowCHinese(96,1,2);//度
</code></pre>
<p>OLED_ShowCHinese(112,1,8);//仪</p>
<p>OW_Init();</p>
<p>SetConfig(CFG_MPS_Single,CFG_Repeatbility_High);</p>
<p>while(1)</p>
<p>{</p>
<p>//printf(&quot;kwin\r\n&quot;);</p>
<p>T= OutputTemp();</p>
<p>sprintf(str,&quot;%6.2fC&quot;,T);</p>
<p>printf(&quot;%s&quot;,str);</p>
<pre><code>OLED\_ShowString(32,5,str,16);


       R\_BSP\_SoftwareDelay(250, BSP\_DELAY\_UNITS\_MILLISECONDS); // NOLINT

       R\_IOPORT\_PinWrite(&amp;g\_ioport\_ctrl, LED1, BSP\_IO\_LEVEL\_LOW);

       R\_IOPORT\_PinWrite(&amp;g\_ioport\_ctrl, LED2, BSP\_IO\_LEVEL\_HIGH);

       R\_BSP\_SoftwareDelay(250, BSP\_DELAY\_UNITS\_MILLISECONDS); // NOLINT

       R\_IOPORT\_PinWrite(&amp;g\_ioport\_ctrl, LED1, BSP\_IO\_LEVEL\_HIGH);

       R\_IOPORT\_PinWrite(&amp;g\_ioport\_ctrl, LED2, BSP\_IO\_LEVEL\_LOW);
</code></pre>
<p>}</p>
<p>#if BSP_TZ_SECURE_BUILD</p>
<pre><code>/\* Enter non-secure code \*/

R\_BSP\_NonSecureEnter();
</code></pre>
<p>#endif</p>
<p>}</p>
<p>代码编译成功后,会有如下提示:</p>
<p><img src="高精度无线人体温度仪.files/高精度无线人体温度仪7823.png" alt="" /></p>
<p>图 13 代码编译成功提示</p>
<p>下载之前需要进行配置:</p>
<p><img src="高精度无线人体温度仪.files/高精度无线人体温度仪7871.png" alt="" /></p>
<p>图 14 程序下载配置</p>
<p>程序调试,可以观测到串口输出如下:</p>
<p><img src="高精度无线人体温度仪.files/高精度无线人体温度仪7923.png" alt="" /></p>
<p>图 15 程序调试输出验证</p>
<p>说明程序运行正常。温度输出为实验室环境温度。</p>
<p>最终的效果图参见第二章节的最终成品图。</p>
<p>系统演示可以查看如下链接:</p>
<p>https://www.bilibili.com/video/BV1WUbJzpEgQ/?vd_source=e36622a05269c0356d6cd566056a2488</p>

yangjiaxu 发表于 2025-8-31 14:43

这个文章全是乱码啊,得好好整理一下才行,不然无法阅读啊

swtman 发表于 2025-9-15 13:45

yangjiaxu 发表于 2025-8-31 14:43
这个文章全是乱码啊,得好好整理一下才行,不然无法阅读啊

现在不是乱码了哈。发布的时候明明好好的。
页: [1]
查看完整版本: 温度测不准?读数据麻烦?来一起从零手搓高精度无线人体温度仪吧