智能冰箱除味器原型开发

更新时间2022-07-13 09:19:11

概况

生活中我们经常会遇到冰箱里面散发一些难闻的气味,厕所里面产生让人反感的气味,鞋柜里面产生一些臭味,车子里面也会有些异味等等,这些气味有时还可以接受,有时很难接受了,为了让我们能享受到食材的新鲜与安全,空气的清新与舒适,我们设计了一款可以歼灭食物菌群,减少因东西杂乱及细菌滋生导致的混杂异味,延长食物保鲜期,降低农药残留,快速去除臭味与霉味的智能除味器。

功能

  • 模式灵活切换:保鲜模式&除味模式。
  • 除味时间选择:可以预约定时除味
  • 除味档位调节:可以多档调节
  • 低电量报警

步骤

  • 第 1 步:硬件设计

    基于涂鸦智能开发的一款 低功耗嵌入式蓝牙模块 TYBN1,设计了一款超低功耗智能除味器。 整个电路设计分为 蓝牙 LE 主控、充电管理电路、稳压电路、升压电路、温湿度检测电路、电量采集电路和负载驱动电路等部分。

    注意:由于是电池供电设备,器件选型需要考虑功耗。

    主控板设计

    原理图

    下载主控板原理图

    PCB

    下载主控板 PCB

    灯板设计

    原理图

    下载灯板原理图

    PCB

    下载灯板 PCB

    电源分析

    充电电路

    充电管理电路:XT2051 是一款用于单芯锂离子电池的恒流/恒压充电电路。该器件包括一个内部功率晶体管,在应用中不需要外部电流检测电阻和阻塞二极管。XT2051 需要最少的外部组件,并满足 USB 总线规范,非常适合便携式应用领域。
    充电指示灯:红色指示灯亮表示正在充电,绿色指示灯亮表示充电完成。

    为了防止电池温度过高或过低对电池造成损坏,XT2051 内置电池集成电路温度监测。电池温度监测是通过测量 TEMP 引脚电压实现,TEMP 引脚电压是在电池 NTC 热敏电阻和电阻分压器网络内,将 XT2051 的 TEMP 引脚电压与芯片的 VLOW 和 VHIGH 两个阈值进行比较,确认是否有电池温度超出正常范围。

    XT2051 中 VLOW 固定在 30% × VIN 中,VHIGH 固定在 60% × VIN 中。如果 TEMP 引脚电压 VTEMP < VLOW 或 VTEMP > VHIGH,说明电池温度过高或过低,芯片暂停工作。如果 TEMP 引脚电压 VTEMP 介于 VLOW 和 VHIGH 之间,则充电周期将继续。

    稳压电路

    通过 LDO 稳压芯片 MD5333 使输出电压稳定在 3.3V,给模组和温湿度传感器等供电。MD5333 低压差(当芯片稳压输出 3.3V、500mA 时, 输入输出压差一般为 400mV),超低静态功耗电流(1.2uA),最高工作电压可达 10V,适合需要较高耐压的应用电路。同时输出具有短路保护功能,有效防止芯片损坏。

    选择这款稳压芯片的原因:

    • 静态功耗超低( 典型值 1.2μA),对于电池供电的设备来说是一款非常合适的芯片。
    • 芯片稳压输出 3.3V, 输出电流达到 500mA,可以满足给模组以及温湿度传感器等供电的需求。

    升压电路

    升压电路:通过 SY7072AABC 芯片(SY7072A 是一种高效、同步、升压转换器)将电压升到 5V,从而给风扇、臭氧发生器、负离子发生器供电。

    选择这款稳压芯片的原因:

    • 静态功耗低( 典型值 5μA)
    • 转换效率较高(如下图所示)。

    电池选型

    样机所用电池是网上买的一款锂电池, 电池容量 3600mAh,带电池保护板(防止过充/过放/短路/过流等保护), 标称电压 3.7V, 充满电电压为 4.2V 的一款带 NTC 保护三线聚合物锂电池。

    • 实物图

    • 电池接口

      锂电池接到 CN1 接口处。

    样机中风扇、臭氧发生器、负离子发生器工作电流最大 900mA,加上模组(工作电流最大 13mA)和温湿度传感器芯片(最大 1.5mA)等工作电流, 总电流是小于 2A 的,因此选择 3600mAh 的锂电池是足够的。

    电路中总工作电流理论值(按最大值计算):Iw= LD0 稳压芯片(静态消耗电流 2.5μA)+ SY7072AABC 升压芯片(静态消耗电流 5μA)+ SHT30 温湿度传感器(最大工作电流 1.5mA)+ 蓝牙模组(最大工作电流 13mA)+ 臭氧发生器(工作电流 600mA)+ 负离子发生器(最大工作电流 200mA)+ 风扇(工作电流 100mA)+ 3 个 MOS 管(每个 MOS 管工作电流 66mA)+ 3 个 LED 灯(每个工作电流约为 320μA)= 1114mA = 1.114A

    电路中休眠状态下电流理论值(按最大值计算):Is= LD0 稳压芯片(静态消耗电流最大值 2.5μA)+ SY7072AABC 升压芯片(休眠时,升压芯片关闭,静态功耗理想值为 0)+ SHT30 温湿度传感器(空闲状态下最大值 2.0μA)+模组(低功耗状态下功耗 240μA)= 244.5μA

    设备可以持续工作时间理论值(最小值):Th=3600mAh ÷ 1114mA=3h

    智能除味器工作在除味模式下:(采用电量测试仪测试,电压输出值 3.9V)

    • 工作在一档的时候,电路中实际总工作电流大小:Iwork1=816mA

    • 工作在二档的时候,电路中实际总工作电流大小:Iwork2=1068mA

    • 工作在三档的时候,电路中实际总工作电流大小:Iwork3=1475mA

    智能除味器工作在保鲜模式下:(采用电量测试仪测试,电压输出值 3.9V)

    • 电路中实际总工作电流大小:Iwork=204mA

    • 智能除味器在低功耗状态下:(蓝牙广播一直开着, 此时 App 未连接)

    • 电路中实际低功耗电流大小:Isleep= 240μA

    • 智能除味器在低功耗状态下:(连接上 App)

    • 电路中实际低功耗电流大小:Isleep= 60μA

    除味模式下:(臭氧发生器和负离子发生器是同时工作的)

    • 设备可以持续工作时间实际值(最小值):Time=3600mA ÷ 1475m ≈ 2.44h

    • 理论值与实际值有点偏差,属于正常现象。(理论值算的是平均值,实际值取的是最小值)

    保鲜模式下:(负离子发生器工作,臭氧发生器不工作)

    • 设备可以持续工作时间实际值(最小值):Time=3600mA ÷ 204mA ≈ 17.65h

    • 低功耗模式下(未连接上 App):设备可以待机时间(最小值):Time=3600mA ÷ 240μA=15000h= 625 天 ≈ 1. 7 年

    • 低功耗模式下(连接上 App):设备可以待机时间(最小值):Time=3600mA ÷ 60μA=60000h= 2500 天 ≈ 6. 85 年

    注意:测试过程中,由于所用仪器的原因,测试数据可能会有偏差。

    传感器部分

    温湿度传感器

    温湿度检测我们使用 SHT30-DIS 温湿度传感器芯片,通过 I2C 协议进行通信,I2C 时钟频率最高支持 1MHz。 芯片工作电压 2.4~5.5V,湿度精度 ±2%RH,温度精度 ±0.3℃, 封装 8 脚 DFN。

    湿度对臭氧的灭活率有影响,因此设计中加了温湿度传感器。如下图臭氧空气消毒效果。

    选择这款芯片的原因:低功耗,温湿度精度较高.

    功能模块

    臭氧发生器

    • 原理

      智能除味器中至关重要的部分就是臭氧发生器了,利用臭氧发生器可以快速除臭和杀菌。臭氧是一种强氧化剂,通过高压电离(或电解、化学、光化学反应)而获得,其产生过程是将空气中的部分氧气分解为氧原子,这些氧原子再和氧分子聚合成臭氧。臭氧的性质极不稳定,生产之后会快速分解,所以,臭氧只能现产现用。产生臭氧的设备叫臭氧发生器。 臭氧发生器的原理以及作用详见 CSDN 上的一篇文章 臭氧味道虽“臭”,架不住它功能强大

    • 实物图

    • 驱动电路

      臭氧发生器模块接到 P2 接口上。 采用直流 5V 供电方式。

      通过模组的 I/O 口 P6 控制臭氧发生器的开通与关断。 当 P6 为低电平时,NMOSFET 管关断,臭氧发生器不工作。当 P6 为高电平时,NMOSFET 管导通,臭氧发生器工作,产生臭氧。

      臭氧发生器的参数:

      • 输入电压:5VDC
      • 使用功率:3W

      注意:臭氧发生器是 5V 供电, 臭氧发生器的工作电流达到 600mA,模组是 3. 3V 供电。同时模组的 I/ O 口输出电流无法驱动臭氧发生器,因此需要加 MOSFET 管来驱动。

    • 臭氧作用

      消毒无死角,杀菌效率高,除异味;用于食材保鲜等。

    负离子发生器

    • 原理

      负离子发生器利用脉冲、振荡电器将低电压升至直流负高压,利用碳毛刷尖端直流高压产生高电晕,高速地放出大量的电子(e-)。而电子并无法长久存在于空气中(存在的电子寿命只有 nS 级),立刻会被空气中的氧分子(O2)捕捉,形成负离子,释放到周围的空气中,净化空气,改善人们的生活环境。这种用人工产生空气负离子的设备就称为空气负离子发生器或负离子发生器。

    • 实物图

    • 驱动电路

      负离子发生器模块接到 P4 接口上。 采用直流 5V 供电方式。

      通过模组的 I/O 口 P5 控制负离子发生器的开通与关断。 当 P5 为低电平时,NMOSFET 管关断,负离子发生器不工作。当 P5 为高电平时,NMOSFET 管导通,负离子发生器工作,净化空气。

      负离子发生器的参数:

      • 输入电压:5VDC
      • 使用功率:≤1W

      注意: 负离子发生器是 5V 供电, 负离子发生器的工作电流需要 200mA 左右,模组是 3. 3V 供电,同时模组的 I/ O 口输出电流无法驱动负离子发生器, 因此需要加 MOSFET 管来驱动。

    • 作用

      负离子发生器产生大量负离子,同时产生微量臭氧。二者的结合很容易吸收各种病毒和细菌,从而引起结构变化或能量转移,导致它们死亡。清新空气、消烟除尘,带负电荷的负离子与漂浮在空气中带正电荷的烟雾粉尘进行电极中和,使其自然沉积。

    风扇

    • 原理

      通过直流电压电磁感应,将电能转化成机械能从而带动风叶转动。

    • 实物图

    • 驱动电路

      风扇接到 P1 接口上。 采用直流 5V 供电方式。

      通过模组的 I/O 口 P7 控制风扇的开通与关断。当 P7 为低电平时,NMOSFET 管关断,风扇不工作。当 P7 为高电平时,NMOSFET 管导通,风扇工作。

      风扇的功率:

      • 额定电压:5VDC
      • 输入电流:最大 100mA
      • 输入功率:最大 0.5W

      注意:风扇是 5V 供电,风扇需要 100mA 左右的输入电流,模组是 3. 3V 供电,同时模组的 I/O 口输出电流无法驱动风扇, 因此需要加 MOSFET 管来驱动。

    • 作用

      用风扇的主要原因是为让智能除味器里面的空气快速流动。一方面不断地向智能除味器里面提供空气,另一方面将产生的臭氧和负离子排出。

    结构部分

    整机结构包含顶盖、内部支撑、主壳体、电源开关、档位按钮、复位按钮六部分以及机牙螺丝组成。获取 STL 文件

    顶盖

    顶盖的主要功能:

    • 将主机挂在冰箱玻璃夹层上
    • 连接内部支架
    • 固定主控板

    内部支撑

    内部支架的主要功能:

    • 连接顶盖与壳体
    • 固定内部元件
    • 分为进风腔体和出风腔体,提高臭氧和负离子的生成效率

    壳体

    壳体的主要功能:

    • 包覆内部元器件
    • 与内部支撑形成进气腔和出气腔
    • 提供充电口、电源开关、档位按钮、复位按钮位置

    电源开关、档位按钮、复位按钮

    • 电源开关:接通和断开整机电源。

    • 档位按钮:切换设备工作档位。
    6
    • 复位按钮:不断电快速重启设备。

  • 第 2 步:创建产品

    产品创建

    本例中,智能除味器用到了温湿度传感器的面板,因此,在创建产品时选择传感品类下面的温湿度传感器,通讯方式选择蓝牙。

    默认选择全部功能点,随意删除可能会导致面板数据丢失或无法打开面板等情况。 面板选择温湿度 Studio 面板,在硬件开发中,选择相应的模组即可,最后领取激活码用于后续开发。

    image.png

    获取 SDK

    1. 获取 原厂 Nordic nRF52832 SDK。本次智能除味器项目开发使用的 SDK 版本是 15.3.0。

      注意:不要将下载的 SDK 放在 Liunx 共享文件夹或者中文路径下,否则在编译时会出现 No such file or directory 等未知错误。

      下载 nRF52832 SDK 后,找到相应 DeviceDownload. zip 文件,进行解压,然后进入 DeviceDownload 文件夹后再次解压 nRF5SDK153059ac345。

    2. 获取 Tuya SDK。

      在环境搭建中,硬件开发步骤选择相应的模组(本例为 TYBN1)后,下载该模组对应的 SDK 资料,解压完成后打开 tuya-ble-sdk-demo-project-nrf52832-V2.1.0 文件夹会出现与其同名的文件夹。

    将此文件夹复制到原厂 SDK 的DeviceDownload\nRF5SDK153059ac345\nRF5_SDK_15.3.0_59ac345\examples\ble_peripheral文件夹下。
    安装 ARM CMSIS4.5.0。下载安装完成后,打开 tuya-ble-sdk-demo-project-nrf52832-V2.1.0\pca10040\s132\arm5_no_packs 文件夹下的 Keil 工程。

    下载芯片对应的安装包

    1. 第一次打开工程会自动下载 nRF52832 芯片对应的安装包。

    2. (可选)安装包下载完成后,如果第一次开发,会显示以下报错信息,可忽略该报错,继续完成安装。

      Cannot execute external request (Install Pack, "NordicSemiconductor:nRF_DeviceFamilyPack"): Pack not found
      Cannot execute external request (Install Pack, "NordicSemiconductor:nRF_DeviceFamilyPack:8.24.1"): Pack not found
      
    3. 按下图所示安装:

    4. 安装完成后重启 Keil 即可编译。

      注意:编译时可能会出现报错 RTE\Device\nRF52832_xxAA\system_nrf52.c(30): error: #5: cannot open source input file "nrf52_erratas.h": No such file or directory 是因为 Keil 版本的问题。

      只需用 DeviceDownload\nRF5SDK153059ac345\nRF5_SDK_15.3.0_59ac345\modules\nrfx\mdk 文件夹下的 system_nrf52.c 替换掉 DeviceDownload\nRF5SDK153059ac345\nRF5_SDK_15.3.0_59ac345\examples\ble_peripheral\tuya-ble-sdk-demo-project-nrf52832-V2.1.0\pca10040\s132\arm5_no_packs\RTE\Device\nRF52832_xxAA 文件夹下的 system_nrf52. c 的文件,然后关闭 keil 工程,再重新打开该工程即可编译通过。

    修改 PID、UUID、Auth_key、MAC 地址

    打开 tuya_ble_sdk_demo 文件夹找到 tuya_ble_sdk_demo.h,将您在 IoT 平台获取的授权码清单中的 UUID、Auth_key、MAC 以及创建产品的 PID 填入下图所示位置。

    tuya_ble_sdk_demo.c 文件中将 use_ext_license_keydevice_id_len 的值分别改为 1、DEVICE_ID_LEN(16),否则上步修改的 uuid、auth_ key 等不会生效。

    设备连线

    编译成功后将 J-Link 烧录器连接到开发板,连线如下:

    模组对应引脚 串口对应引脚
    VCC VCC(3.3V)
    模组对应引脚 JLINK 对应引脚
    SWDIO SWDIO
    SWC SWCLK
    GND GND

    查看日志

    日志查看使用 J-Link RTT Viewer 软件。

    1. 下载完成后,在开始菜单中搜索 J-Flash Vx.xxb(x.xx 版本号) 并打开,单击 File > New Project,芯片选择 nRF52832_xxAA,单击 OK

    2. 单击 File > Open data file,选中 tuya-ble-sdk-demo-project-nrf52832-V2.1.0\pca10040\s132\arm5_no_packs\hex\material 文件夹下的 s132_nrf52_6.1.1_softdevice.hex 文件。

    3. 单击 Target > Connect,连接成功后,接着单击 Target > Production Programming 开始下载协议栈固件。下载成功后,下方日志口会有 Data file opened successfully 字样。

    4. 最后单击 Target > Disconnect 断开连接。

    Log 默认是关闭的,通过修改宏来使能日志,操作步骤如下:

    1. 找到 tuya-ble-sdk-demo-project-nrf52832-V2.1.0\tuya_ble_sdk_demo\board\nRF52832\tuya_ble_port 文件夹下的 custom_tuya_ble_config.h 文件,将第 113 行 TUYA_App_LOG_ENABLE 日志输出使能。

    ​2. 找到 ble_peripheral\tuya-ble-sdk-demo-project-nrf52832-V2.1.0\tuya_ble_sdk_demo\board 文件夹下的 board.h 文件。 将第 38 行 TY_LOG_ENABLE 日志输出使能。

    ​3. 修改、编译完成后将 hex 文件烧录到模组。

    日志查看方法如下:

    1. 打开 J-link RTT Viewer Vx.xxb 后自动弹出以下对话框:

    2. 选择 USB,在Specify Target Device 中单击出现下面的弹窗,在红框内输入nRF52832_xxAA回车后双击选定。 最后依次选择上图红框选项单击 OK 完成设置。

    3. 当界面内出现以下内容说明连接成功,可以正常查看日志。

    修改测试宏

    打开工程目录 tuya_ble_sdk_demo 下的 tuya_ble_sdk_test.h 文件,将第 29 行宏定义 TUYA_BLE_SDK_TEST 关闭,该宏为测试模式的开关,打开会导致测试功能模块占用相关 I/O 口资源,使部分 I/O 口以及相关外设无法正常使用。

    具体信息,可参考 nRF52832 学习笔记

  • 第 3 步:软件设计

    代码结构

    智能除味器软件代码结构如下:

    └── tuya_ble_sdk_demo
    ├── App
    ├── board
    │ ├── nRF52832
    │ │ ├── include
    │ │ │ ├── tuya_Appointment_timing_function.h
    │ │ │ ├── tuya_battery_check.h
    │ │ │ ├── tuya_ble_handle.h
    │ │ │ ├── tuya_deodorizer_temperature_humidity.h
    │ │ │ ├── tuya_key_process.h
    │ │ │ └── tuya_pwm.h
    │ │ ├── src
    │ │ │ ├── tuya_Appointment_timing_function.c 设备定时
    │ │ │ ├── tuya_battery_check.c 除味器完成回连上报数据
    │ │ │ ├── tuya_ble_handle.c DP 点数据处理
    │ │ │ ├── tuya_deodorizer_temperature_humidity.c 自动档位调节
    │ │ │ ├── tuya_key_process.c 手动档位调节
    │ │ │ └── tuya_pwm.c 除味模式和保鲜模式

    工作模式

    智能除味器有除味和保鲜两种工作模式:

    模式 功能
    除味模式 臭氧离子发生器和负离子发生器一起工作
    保鲜模式 臭氧离子发生器关闭,负离子发生器工作

    其中,除味模式和保鲜模式分别有强、中、弱三个档位调节。通过对臭氧离子发生器和负离子发生器相连引脚进行不同的 PWM 占空比设置,使臭氧离子发生器和负离子发生器处于不同的工作强度,模拟出强、中、弱三档。PWM 占空比对应关系如下:

    档位 PWM 占空比
    强档 100%
    中档 70%
    弱档 50%

    为了使面板内容更加丰富,本次除味器面板选择温湿度 Studio 面板,显示工作过程中的温湿度并形成温湿度曲线对数据进行记录。在产品创建时默认选择原有的 DP 功能点。随意删除可能会导致面板数据丢失或无法打开面板等情况。具体的 DP 点介绍如下:

    自定义功能

    DP 点名称 DP ID 数据传输类型 数据类型
    工作模式 101 可下发可上报(rw) 枚举型(Enum)
    档位 103 可下发可上报(rw) 枚举型(Enum)
    定时 104 可下发可上报(rw) 枚举型(Enum)

    在温湿度的标准功能中, 将 DP ID 3、4 作为电池电量报警和电池电量显示的两个功能点来使用。

    智能除味器处于除味模式一档档位的功能代码实现:

    /**
    * @function: ty_ozone_first_gear_pwm_init
    * @brief: Ozone negative ion generator working mode
    * @param[]: void
    * @return: success -> 0   fail -> else
    */
    uint32_t ty_ozone_first_gear_pwm_init(void)
    {
        uint32_t ret = 0;
        ozone_pwm.pin = OZONE_PWM_PIN;            //臭氧离子发生器连接引脚
        ozone_pwm.pin2 = NEGATIVE_ION_PWM_PIN;    //负离子发生器连接引脚
        ozone_pwm.polarity = 0;
        ozone_pwm.freq = 1000;
        ozone_pwm.duty = 50;
        negative_ion_pwm.duty = 50;
    
        ret = ty_pwm_init(&ozone_pwm);
        if(ret != 0){
            TUYA_App_LOG_INFO("OZONE first pwm failed to initialize");
            return 1;
        }
        ty_pwm_start(&ozone_pwm);
        return 0;
    }
    

    智能除味器处于保鲜模式一档档位的功能代码实现:

    /**
    * @function: ty_negative_ion_first_gear_pwm_init
    * @brief: Anion generator working mode
    * @param[]: void
    * @return: success -> 0   fail -> else
    */
    uint32_t ty_negative_ion_first_gear_pwm_init(void)
    {
        uint32_t ret = 0;
        negative_ion_pwm.pin = NRFX_PWM_PIN_NOT_USED;
        negative_ion_pwm.pin2 = NEGATIVE_ION_PWM_PIN;
        negative_ion_pwm.polarity = 0;
        negative_ion_pwm.freq = 1000;
        negative_ion_pwm.duty = 50;
    
        ret = ty_pwm_init(&negative_ion_pwm);
        if (ret != 0)
        {
            TUYA_App_LOG_INFO("NEGATIVE_ION first pwm failed to initialize");
            return 1;
        }
        return 0;
    }
    

    档位调节

    档位分为自动档位和手动档位两种调节方式。

    自动档位调节

    除味器通过 SHT30 温湿度传感器获取温湿度,根据不同的温湿度数据自动进行档位调节。调节后,会将改变后的档位 DP 进行上报给 App 面板。温湿度处理逻辑和档位对应关系如下:

    温度 湿度 档位
    (temperature > 10) && (temperature < 15) (humidity > 60) && (humidity < 65) 强档
    (temperature > 15) && (temperature < 22) (humidity > 30) && (humidity < 50) 中档
    (temperature > 22) && (temperature < 29) (humidity > 55) && (humidity < 75) 弱档

    除味器自动档位调节以及自动挡位调节后档位 DP 上报的功能代码如下:

    /**
    * @function: ty_gear_adjustment_using_temmperature_humidity
    * @brief: Automatic gear adjustment according to different temperature and humidity
    * @param[]: void
    * @return: success -> 0   fail -> else
    */
    uint32_t ty_gear_adjustment_using_temmperature_humidity(void)
    {
        int32_t temperature = 0;
        int32_t humidity = 0;
        temperature = (int32_t)tuya_sht3x_collect_state.temperature_value;
        humidity = (int32_t)tuya_sht3x_collect_state.humidity_value;
    
        if ((temperature > 10) && (temperature < 15) && (humidity > 60) && (humidity < 65))
        {
            if (mode_selection.fresh_keeping_mode == 1)
            {
                ty_ozone_three_gear_pwm_init();
                ty_indicator_light();
                ty_third_gear();
            }
            if (mode_selection.deodorization_mode == 1)
            {
                ty_ozone_three_gear_pwm_init();
                ty_negative_ion_three_gear_pwm_init();
                ty_indicator_light();
                ty_third_gear();
            }
        }
        else if ((temperature > 15) && (temperature < 22) && (humidity > 30) && (humidity < 50))
        {
            if (mode_selection.fresh_keeping_mode == 1)
            {
                ty_ozone_second_gear_pwm_init();
                ty_indicator_light();
                ty_second_gear();
            }
            if (mode_selection.deodorization_mode == 1)
            {
                ty_ozone_second_gear_pwm_init();
                ty_negative_ion_second_gear_pwm_init();
                ty_indicator_light();
                ty_second_gear();
            }
        }
        else if ((temperature > 22) && (temperature < 29) && (humidity > 55) && (humidity < 75))
        {
            if (mode_selection.fresh_keeping_mode == 1)
            {
                ty_ozone_first_gear_pwm_init();
                ty_indicator_light();
                ty_first_gear();
            }
            if (mode_selection.deodorization_mode == 1)
            {
                ty_ozone_first_gear_pwm_init();
                ty_negative_ion_first_gear_pwm_init();
                ty_indicator_light();
                ty_first_gear();
            }
        }
        else
        {
            ;
        }
    
        return 0;
    }
    /**
    * @function: ty_first_gear
    * @brief: Adjust one gear to report DP
    * @param[]: void
    * @return: success -> 0   fail -> else
    */
    uint32_t ty_first_gear(void)
    {
        uint32_t ret = 0;
        uint8_t dp_length = 5;
        uint8_t send_buf[] = {0};
        send_buf[] = tuya_dp_id.gear_adjustment_id;
        send_buf[] = tuya_dp_id.gear_adjustment_type;
        send_buf[] = 0x00;
        send_buf[] = 0x01;
        send_buf[] = 0x00;
        ret = tuya_ble_dp_data_send(tuya_dp_id.sn_data + 2, DP_SEND_TYPE_ACTIVE, DP_SEND_FOR_CLOUD_PANEL, DP_SEND_WITHOUT_RESPONSE, send_buf, dp_length);
        return 0;
    }
    

    手动档位调节

    通过短按按键实现除味器的强、中、弱档位循环切换。调节后,会将改变后的档位 DP 进行上报给 App 面板。核心功能代码如下:

    /**
    * @function: ty_device_key_gear_adjust
    * @brief: Ozone generator and anion generator gear adjustment
    * @param[]: void
    * @return: success -> 0   fail -> else
    */
    uint32_t ty_device_key_gear_adjust(void)
    {
        uint32_t gear_mode_ret = 0;
        uint32_t pin_level_state = 0;
        pin_level_state = ty_reset_key_state.key_short_press;
        if (pin_level_state == 1)
        {
            ty_delay_us(10);
            if (pin_level_state == 1)
            {
                gear_mode_ret = ty_get_device_gear_mode();              //获取当前的档位
    
                switch (gear_mode_ret)
                {
                    case 1:
                        if(mode_selection.fresh_keeping_mode == 1)
                        {
                            ty_negative_ion_second_gear_pwm_init();     //保鲜模式二档
                            ty_indicator_light();
                            ty_second_gear();                           //上报当前档位
                        }
                        if(mode_selection.deodorization_mode == 1)
                        {
                            ty_ozone_second_gear_pwm_init();            //除味模式二档
                            ty_indicator_light();
                            ty_second_gear();                           //上报当前档位
                        }
    
                        break;
                    case 2:
                        if (mode_selection.fresh_keeping_mode == 1)
                        {
                            ty_negative_ion_three_gear_pwm_init();      //保鲜模式二档
                            ty_indicator_light();
                            ty_third_gear();                            //上报当前档位
                        }
                        if (mode_selection.deodorization_mode == 1)
                        {
                            ty_ozone_three_gear_pwm_init();             //除味模式二档
                            ty_indicator_light();
                            ty_third_gear();                            //上报当前档位
                        }
    
                        break;
                    case 3:
                        if (mode_selection.fresh_keeping_mode == 1)
                        {
                            ty_negative_ion_first_gear_pwm_init();      //保鲜模式二档
                            ty_indicator_light();
                            ty_first_gear();                            //上报当前档位
                        }
                        if (mode_selection.deodorization_mode == 1)
                        {
                            ty_ozone_first_gear_pwm_init();             //除味模式二档
                            ty_indicator_light();
                            ty_first_gear();                            //上报当前档位
                        }
    
                        break;
                    default:
                        break;
                }
                ty_sht3x_reset(); // i2c 禁止初化
                ty_sht3x_init();  //温湿度传感器初始化
    
            }
        }
        ty_reset_key_state.key_short_press = 0;
        return 0;
    
    }
    

    低功耗

    如果设备处于低电量或者设备定时到达,则进入低功耗。然后智能除味器需要上报低电量 DP 给 App 面板,App 面板上进行低电量报警。

    智能除味器进入低功耗并将低电量上报给 App 面板功能代码如下:

    /**
    * @function:ty_device_stop_work
    * @brief: Turn off the peripherals and the device enters low power consumption
    * @param[]: void
    * @return: success -> 0   fail -> else
    */
    
    uint32_t ty_device_stop_work(void)
    {
        ty_sht3x_single_messure();                //开启温湿度传感器单次测量模式,降低功耗
        nrf_gpio_pin_write(BOOST_PIN,0);          //关闭升压电路
        ty_switch_off_fan();                      //关闭电扇
        ty_switch_off_indicator_light();          //关闭指示灯
        ty_negative_ion_pwm_stop();               //关闭臭氧离子发生器和负离子发生器
        //ty_ble_stop_adv();                      //蓝牙广播关闭函数
        ty_uart_uninit();                          //禁止串口初始化
        ty_uart2_uninit();                          //禁止串口初始化
        ty_rtc_uninit();                            // 禁止  RTC 初始化
        ty_spi_disable();                           // 禁止  spi 初始化
    
        ty_adc_uninit(&battery_check_adc);         //禁止电量检测
        ty_sht3x_reset();                         //关闭温湿度传感器
        low_power.low_power_glag = 1;               //设备进入低功耗状态
        Appointment_timing_close.reservation_timing_off_flag = 1;
        return 0;
    }
    /**
    * @function:ty_low_power_dp_send
    * @brief: Low power report
    * @param[]: void
    * @return: success -> 0   fail -> else
    */
    uint32_t ty_low_power_dp_send(void)
    {
        uint32_t ret = 0;
        uint8_t dp_length = 5;
        uint8_t send_buf[] = {0};
        send_buf[] = tuya_dp_id.low_power_alarm_id;
        send_buf[] = tuya_dp_id.low_power_alarm_type;
        send_buf[] = 0x00;
        send_buf[] = 0x01;
        send_buf[] = 0x00;
    
        ret = tuya_ble_dp_data_send(tuya_dp_id.sn_data, DP_SEND_TYPE_ACTIVE, DP_SEND_FOR_CLOUD_PANEL, DP_SEND_WITHOUT_RESPONSE, send_buf, dp_length);
        if(ret != 0)
        {
            TUYA_App_LOG_INFO("ty_low_power_dp_send  failed to send");
        }
        return 0;
    }
    

    设备定时

    预约定时通过 RTC 来实现,设备工作时长有四种时长选择:

    设备运行时长 设备关闭
    15 分钟 设别运行 15 分钟后关闭
    30 分钟 设备运行 30 分钟后关闭
    1 小时 设备运行 1 小时后关闭
    2 小时 设备运行 2 小时后关闭

    在 App 端对设智能除味器定时 15 分钟工作时长为例,首先需要计算出 15 分后 RTC 时间戳,此计算代码如下:

    /**
    * @function:ty_rtc_get_time_and_fifteen_points_update_flag
    * @brief: Make an Appointment for 15 minutes, obtain the time and update the flag bit
    * @param[]: void
    * @return: success -> 0   fail -> else
    */
    uint32_t ty_rtc_get_time_and_fifteen_points_update_flag(void)
    {
        uint32_t current_time = 0;          // 获取当前  RTC 时间
        ty_rtc_get_time(&current_time);
        Appointment_time_arrival.time_end = current_time + AppOINTMENT_TIMING_FIFTEEN_POINTS;  // 获取当前时间加上  15 分钟后的时间戳
    
        time_end_flag_bit.time_end_flag = 1;
    
        return 0;
    }
    

    然后,在 main() 函数中判断当前的时间戳是否大于等于 Appointment_time_arrival.time_ end 结构体成员的值。如果满足条件,则设备调用 ty_device_stop_work() 接口,设备进入低功耗状态。核心代码如下:

    /**
    * @function:ty_check_Appointment_time
    * @brief: Determine whether the Appointment time has arrived
    * @param[]: void
    * @return: success -> 0   fail -> else
    */
    uint32_t ty_check_Appointment_time(void)
    {
        uint32_t Appointment_time = 0;
        if(!time_end_flag_bit.time_end_flag)
            return 0;
    
        while (time_end_flag_bit.time_end_flag)
        {
            ty_rtc_get_time(&Appointment_time);
            if (Appointment_time >= Appointment_time_arrival.time_end)    //判断预约除味器工作时长时间是否到达
            {
                Appointment_time_arrival.time_end = 0;
                time_end_flag_bit.time_end_flag = 0;
                ty_device_stop_work();                                   //关闭设备,进入低功耗状态
            }
        }
    
        return 0;
    }
    

小结

​至此智能冰箱除味器样机就完成了,它可以 App 控制,也可以按键控制。具有模式切换、档位调节、自动定时、低电量告警等功能。智能除味器使用臭氧发生器与负离子发生器,产生臭氧与负离子,可以杀菌消毒、去除异味、净化空气、食材保鲜,是非常棒的智能硬件产品。在这款智能除味器的基础上还有很多功能可以深入开发,对其功能进行完善。同时您可以基于涂鸦 IoT 开发平台丰富它的功能,也可以更加方便地搭建更多智能产品原型,加速智能产品的开发流程。