基于STM32的智能水杯设计
摘要:本设计基于STM32F103C8T6单片机,实现了一款智能水杯,具备水温、水位实时监测,灯光指示,红外感应,自动模式、定时模式、阈值设置等功能,并通过蓝牙传输控制数据至手机APP。系统采用DS18B20水温传感器、水位传感器、OLED显示屏、红外感应模块等,实现了对水温、水位的精确监测与显示,以及多种模式的智能控制。手机APP可远程接收数据、设置定时时间和阈值,为用户提供了便捷、智能的饮水体验。
关键词:STM32F103C8T6;智能水杯;水温监测;水位监测;灯光指示;红外感应;自动模式;定时模式;阈值设置;蓝牙传输;手机APP
1 引言
1.1 研究背景
随着人们生活水平的提高,对健康和生活品质的关注度日益增加。饮水作为日常生活中不可或缺的部分,其安全性和便利性受到了广泛关注。智能水杯作为一种新兴的智能家居产品,能够实时监测水温、水位等信息,并提供智能提醒和控制功能,有助于用户养成良好的饮水习惯,保障饮水安全。
1.2 研究目的与意义
本设计的目的是开发一款基于STM32的智能水杯,集成多种传感器和功能模块,实现对水温、水位的实时监测与显示,以及多种模式的智能控制。通过手机APP实现远程监控和控制,提高用户的饮水体验和健康管理水平。该设计对于推动智能家居产品的发展,促进人们健康生活方式的形成具有重要的现实意义。
1.3 国内外研究现状
在国外,智能家居产品发展较为成熟,智能水杯已经有一定的市场应用。一些先进的智能水杯产品不仅具备基本的监测功能,还集成了更多的健康管理功能,如饮水提醒、水质检测等。在国内,随着物联网技术的快速发展,智能水杯也逐渐受到关注,但目前市场上的产品功能相对单一,智能化程度有待提高。因此,研发一款功能丰富、智能化程度高的智能水杯具有重要的市场前景和应用价值。
2 系统总体设计
2.1 系统设计目标
本系统旨在设计一款基于STM32F103C8T6单片机的智能水杯,实现以下功能:
- 实时监测水温、水位,并通过OLED显示屏显示实时数据。
- 具备自动模式、定时模式和阈值设置模式,用户可根据需求切换模式。
- 在定时模式下,可设置定时时间,时间到后通过灯光提醒用户饮水。
- 具备红外感应功能,当有人触碰水杯时停止提醒,液晶重新倒计时。
- 根据水位高低,通过不同LED灯进行水量显示。
- 水温低于设定阈值时,打开继电器外接加热片模拟加热;高于阈值时,关闭继电器停止加热。
- 通过蓝牙模块将数据传输至手机APP,实现远程监控和控制。
2.2 系统总体框架设计
本系统主要由主控单元、传感器模块、执行机构模块、显示模块、通信模块和手机APP六个部分组成。系统总体框架如图2-1所示。
图2-1 系统总体框架图 |
- 主控单元:采用STM32F103C8T6单片机作为核心处理器,负责接收传感器数据、处理逻辑判断以及控制执行机构模块、显示模块和通信模块。
- 传感器模块:包括水温传感器(DS18B20)和水位传感器,用于采集水温、水位数据并传输给主控单元。
- 执行机构模块:包括继电器和外接加热片,用于根据水温阈值控制加热功能;还包括多个LED灯,用于水量显示和饮水提醒。
- 显示模块:采用OLED显示屏,用于实时显示水温、水位等数据。
- 通信模块:采用蓝牙模块,负责将主控单元传输过来的数据发送到手机APP,并接收手机APP发送的控制指令。
- 手机APP:用于远程接收水杯数据、设置定时时间和阈值,并实现远程控制功能。
3 硬件设计
3.1 STM32主控模块
本系统采用STM32F103C8T6单片机作为主控芯片,该芯片基于ARM Cortex-M3内核,具有高性能、低功耗和丰富的外设接口。在硬件设计中,需要将单片机的各个引脚与各个模块进行正确的连接,并配置相应的外设参数。例如,将DS18B20水温传感器的DATA引脚连接到单片机的GPIO口,配置该GPIO口为输入模式,用于读取水温数据;将水位传感器的输出引脚连接到单片机的ADC接口,配置ADC接口的参数,用于采集水位数据。
3.2 传感器模块
3.2.1 水温传感器
本系统采用DS18B20水温传感器来检测水温。DS18B20传感器具有体积小、精度高、抗干扰能力强等优点,能够通过单线方式与STM32单片机进行通信,提供准确的温度数据。在硬件设计中,DS18B20的VCC引脚连接3.3V电源,GND引脚接地,DATA引脚通过4.7KΩ上拉电阻连接到单片机的GPIO口,以保证信号的稳定性。
3.2.2 水位传感器
水位传感器采用基于电容式原理的传感器,能够准确感知水杯内的液体变化。传感器的输出为模拟信号,通过STM32单片机的ADC接口进行采集。在硬件设计中,将水位传感器的输出引脚连接到单片机的ADC通道,配置ADC的采样时间和参考电压等参数,确保采集到的水位数据准确可靠。
3.3 执行机构模块
3.3.1 继电器与加热片
继电器用于控制外接加热片的通断,当水温低于设定的阈值时,单片机控制继电器闭合,使加热片开始工作;当水温高于阈值时,单片机控制继电器断开,停止加热。在硬件设计中,将继电器的控制引脚连接到单片机的GPIO口,配置该GPIO口为输出模式,通过高低电平控制继电器的开关状态。加热片通过继电器与电源相连,实现加热功能。
3.3.2 LED灯
系统采用多个LED灯进行水量显示和饮水提醒。当水位低于30%时,LED3亮起;水位在30% - 50%之间时,LED2亮起;水位高于50%时,LED1亮起。在定时模式下,时间到后全部灯光打开进行提醒喝水,当红外感应到有人触碰水杯时,灯光停止闪烁,液晶重新倒计时。在硬件设计中,将各个LED灯的正极通过限流电阻连接到单片机的GPIO口,负极接地,通过控制GPIO口的电平来控制LED灯的亮灭。
3.4 显示模块
本系统采用OLED显示屏作为显示模块,用于实时显示水温、水位等数据。OLED显示屏具有高对比度、低功耗、视角广等特点,能够清晰显示文字和图像。在硬件设计中,将OLED显示屏的SCL、SDA引脚分别连接到单片机的I2C接口的SCL、SDA引脚,配置I2C接口的参数,实现单片机与OLED显示屏之间的通信。
3.5 通信模块
本系统采用蓝牙模块实现与手机APP的通信。蓝牙模块通过UART接口与STM32单片机相连,在硬件设计中,将蓝牙模块的TXD、RXD引脚分别连接到单片机的RXD、TXD引脚,实现数据的双向传输。同时,需要配置蓝牙模块的波特率、数据位、停止位等参数,确保与单片机的通信正常。
3.6 红外感应模块
红外感应模块用于检测是否有人触碰水杯。当有人触碰水杯时,红外感应模块输出相应的信号,单片机接收到信号后停止灯光提醒,液晶重新倒计时。在硬件设计中,将红外感应模块的输出引脚连接到单片机的GPIO口,配置该GPIO口为输入模式,通过读取该引脚的电平状态来判断是否有人触碰水杯。
3.7 电源模块
本系统采用5V锂电池作为电源模块,通过电源管理电路实现锂电池的充电、放电和过流过压保护等功能。在硬件设计中,选择合适的电源管理芯片,将锂电池的输出电压转换为适合单片机和其他模块工作的电压,确保系统在各种环境下的稳定运行。
4 软件设计
4.1 系统初始化
在系统启动后,首先需要进行系统初始化操作。系统初始化包括STM32单片机初始化、传感器模块初始化、执行机构模块初始化、显示模块初始化、通信模块初始化和红外感应模块初始化等。
4.1.1 STM32单片机初始化
STM32单片机初始化包括时钟系统初始化、GPIO初始化、I2C初始化、ADC初始化、UART初始化等。在时钟系统初始化中,配置系统时钟源和时钟分频系数等参数;在GPIO初始化中,配置各个GPIO口的输入输出模式、上拉/下拉电阻等参数;在I2C初始化中,配置I2C接口的时钟频率、从机地址等参数;在ADC初始化中,配置ADC通道、采样时间等参数;在UART初始化中,配置波特率、数据位、停止位等参数。
4.1.2 传感器模块初始化
传感器模块初始化包括水温传感器初始化和水位传感器初始化。在水温传感器初始化中,配置DS18B20的工作模式,发送复位命令和跳过ROM命令,等待传感器响应。在水位传感器初始化中,配置ADC通道的采样时间和参考电压等参数。
4.1.3 执行机构模块初始化
执行机构模块初始化包括继电器初始化和LED灯初始化。在继电器初始化中,将控制继电器的GPIO口初始化为低电平,使继电器处于断开状态。在LED灯初始化中,将控制LED灯的GPIO口初始化为低电平,使LED灯处于熄灭状态。
4.1.4 显示模块初始化
显示模块初始化包括OLED显示屏初始化。在初始化过程中,发送一系列的初始化命令,设置OLED显示屏的显示模式、对比度、扫描方向等参数,并清空显示缓冲区。
4.1.5 通信模块初始化
通信模块初始化包括蓝牙模块初始化。在初始化过程中,配置蓝牙模块的波特率、数据位、停止位等参数,使其与单片机的UART接口匹配。
4.1.6 红外感应模块初始化
红外感应模块初始化包括配置控制红外感应模块的GPIO口为输入模式,并读取初始的电平状态。
4.2 数据采集与处理
在系统运行过程中,需要不断采集水温、水位数据并进行处理。数据采集与处理流程如图4-1所示。
图4-1 数据采集与处理流程图 |
- 数据采集:通过DS18B20水温传感器采集水温数据,通过水位传感器采集水位数据。
- 数据滤波:对采集到的数据进行滤波处理,去除噪声和干扰信号,提高数据的准确性。例如,采用滑动平均滤波算法,对连续采集的多个数据进行平均计算,得到较为稳定的水温、水位值。
- 数据处理:根据滤波后的数据,进行相应的处理。如将水位数据转换为百分比形式,便于在OLED显示屏上显示。
- 数据存储:将处理后的数据存储到STM32单片机的闪存中或通过蓝牙模块发送到手机APP进行远程存储。
4.3 模式切换与控制
本系统具备自动模式、定时模式和阈值设置模式,用户可通过按键进行模式切换。
4.3.1 自动模式
在自动模式下,系统根据水温阈值自动控制加热片的通断。当水温低于设定的阈值时,单片机控制继电器闭合,使加热片开始工作;当水温高于阈值时,单片机控制继电器断开,停止加热。同时,系统实时监测水位,并通过LED灯进行水量显示。
4.3.2 定时模式
在定时模式下,用户可通过按键设置定时时间。系统开始倒计时,时间到后通过全部灯光打开进行提醒用户饮水。当红外感应到有人触碰水杯时,灯光停止闪烁,液晶重新倒计时。定时模式的控制流程如图4-2所示。
图4-2 定时模式控制流程图 |
4.3.3 阈值设置模式
在阈值设置模式下,用户可通过按键三和按键四进行水温阈值的加减设置。设置完成后,系统将新的阈值存储到单片机的闪存中,并在后续的自动模式下按照新的阈值进行控制。
4.4 蓝牙通信
蓝牙通信模块负责将主控单元传输过来的数据发送到手机APP,并接收手机APP发送的控制指令。蓝牙通信流程如图4-3所示。
图4-3 蓝牙通信流程图 |
- 数据发送:将采集到的水温、水位数据以及系统的工作状态等信息打包后通过蓝牙模块发送到手机APP。
- 指令接收:接收手机APP发送的控制指令,如模式切换指令、定时时间设置指令、阈值设置指令等,并解析后传输给主控单元进行处理。
4.5 手机APP设计
手机APP用于远程接收水杯数据、设置定时时间和阈值,并实现远程控制功能。手机APP界面设计如图4-4所示。
图4-4 手机APP界面设计图 |
- 数据接收与显示:实时接收并显示水温、水位数据以及系统的工作状态,如当前模式、定时剩余时间等。同时,通过指示灯的形式显示当前水量。
- 定时时间设置:允许用户设置定时时间,并将设置的时间发送到智能水杯系统。
- 阈值设置:允许用户设置水温阈值,并将设置的阈值发送到智能水杯系统。
- 远程控制:允许用户远程切换系统模式,如从自动模式切换到定时模式或阈值设置模式。
5 系统测试与结果分析
5.1 硬件连接测试
在硬件连接完成后,首先需要进行硬件连接测试。硬件连接测试包括各个模块之间的连接测试、电源模块测试等。通过万用表等工具检查各个引脚的连接是否正确,确保电源模块的输出电压稳定,各个模块能够正常供电。
5.2 软件功能测试
在硬件连接测试完成后,需要进行软件功能测试。软件功能测试包括系统初始化测试、数据采集与处理测试、模式切换与控制测试、蓝牙通信测试以及手机APP功能测试等。
5.2.1 系统初始化测试
通过调试工具观察STM32单片机的初始化过程是否正常完成,包括各个外设的初始化状态。检查OLED显示屏是否能够正常显示初始化信息,各个LED灯是否处于初始熄灭状态。
5.2.2 数据采集与处理测试
通过加热或冷却水杯中的水,观察DS18B20水温传感器采集到的水温数据是否准确变化;通过改变水位,观察水位传感器采集到的水位数据是否准确变化。同时,检查数据滤波算法是否有效,处理后的数据是否稳定可靠。
5.2.3 模式切换与控制测试
通过按键切换不同的模式,观察系统是否能够正确响应并进入相应的模式。在自动模式下,检查加热片的控制是否根据水温阈值正常工作;在定时模式下,设置不同的定时时间,观察倒计时是否准确,时间到后灯光提醒是否正常;在阈值设置模式下,通过按键三和按键四进行阈值设置,检查设置后的阈值是否能够正确存储并在自动模式下生效。
5.2.4 蓝牙通信测试
通过蓝牙调试工具测试蓝牙模块是否正常工作。观察手机APP是否能够正常接收水杯发送的数据,并能够正确显示;同时,通过手机APP发送控制指令,观察水杯系统是否能够正确接收并执行相应的操作。
5.2.5 手机APP功能测试
测试手机APP的各个功能是否正常,如数据接收与显示是否准确、定时时间设置和阈值设置是否有效、远程控制是否能够正常切换系统模式等。
5.3 系统性能测试
在系统功能测试完成后,需要进行系统性能测试。系统性能测试包括系统的响应时间、稳定性、可靠性等。
5.3.1 响应时间测试
通过模拟各种操作,如按键切换模式、设置定时时间等,测试系统的响应时间,包括从操作发生到系统做出相应反应的时间间隔。通过多次测试取平均值来评估系统的响应时间性能。
5.3.2 稳定性测试
通过长时间运行系统(如连续运行7*24小时)观察系统的工作情况是否稳定可靠。记录系统出现的异常情况(如数据丢失、通信中断、控制失灵等)并分析其原因进行改进。
5.3.3 可靠性测试
通过模拟各种复杂环境(如温度变化、湿度变化、电磁干扰等)测试系统的可靠性表现。观察系统在不同环境下的工作情况并记录出现的异常情况进行分析和改进。
5.4 测试结果分析
通过上述测试得出以下结论:
- 系统硬件连接正确无误,各个模块能够正常供电和工作。
- 系统各个功能模块正常工作,能够实现预期功能,包括数据采集与处理、模式切换与控制、蓝牙通信以及手机APP功能等。
- 系统性能表现良好,响应时间短、稳定性高、可靠性强。
6 结论与展望
6.1 结论
本设计基于STM32F103C8T6单片机,成功实现了一款智能水杯,具备水温、水位实时监测,灯光指示,红外感应,自动模式、定时模式、阈值设置等功能,并通过蓝牙传输控制数据至手机APP。系统经过硬件连接测试、软件功能测试和系统性能测试,结果表明系统硬件连接正确,各个功能模块正常工作,性能表现良好,能够为用户提供便捷、智能的饮水体验。
6.2 展望
未来可以在以下几个方面对系统进行改进和优化:
- 增加更多传感器:可以增加水质传感器等,监测水杯中水的质量,为用户提供更全面的饮水信息。
- 优化算法:采用更先进的算法对采集到的数据进行分析和处理,提高系统的智能化程度和准确性。例如,采用机器学习算法根据用户的饮水习惯进行个性化的饮水提醒。
- 增强用户体验:优化手机APP的界面设计和交互方式,增加更多的功能,如饮水记录查询、健康建议等,提高用户体验和满意度。
- 提高系统稳定性:增加冗余设计和容错机制,提高系统的稳定性和可靠性,确保系统在各种复杂环境下都能正常工作。例如,采用看门狗电路防止系统死机。
参考文献
[此处根据实际引用情况列出参考文献]
附录:手机APP源码(示例)
java
// 以下为手机APP部分功能的示例源码(以Android平台为例) | |
// MainActivity.java | |
public class MainActivity extends AppCompatActivity { | |
private TextView temperatureText, waterLevelText; | |
private Button modeButton, setTimeButton, setThresholdButton; | |
private BluetoothAdapter bluetoothAdapter; | |
private BluetoothDevice connectedDevice; | |
private ConnectThread connectThread; | |
private ConnectedThread connectedThread; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
temperatureText = findViewById(R.id.temperature_text); | |
waterLevelText = findViewById(R.id.water_level_text); | |
modeButton = findViewById(R.id.mode_button); | |
setTimeButton = findViewById(R.id.set_time_button); | |
setThresholdButton = findViewById(R.id.set_threshold_button); | |
// 初始化蓝牙 | |
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); | |
if (bluetoothAdapter == null) { | |
Toast.makeText(this, "设备不支持蓝牙", Toast.LENGTH_SHORT).show(); | |
finish(); | |
} | |
// 检查蓝牙是否开启 | |
if (!bluetoothAdapter.isEnabled()) { | |
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); | |
startActivityForResult(enableBtIntent, 1); | |
} | |
// 模拟接收数据并显示 | |
// 实际应用中,这里应该是从蓝牙线程接收数据并更新UI | |
updateDisplay("25°C", "50%"); | |
modeButton.setOnClickListener(v -> { | |
// 切换模式逻辑 | |
showModeSelectionDialog(); | |
}); | |
setTimeButton.setOnClickListener(v -> { | |
// 设置定时时间逻辑 | |
showTimePickerDialog(); | |
}); | |
setThresholdButton.setOnClickListener(v -> { | |
// 设置阈值逻辑 | |
showThresholdSettingDialog(); | |
}); | |
} | |
private void updateDisplay(String temperature, String waterLevel) { | |
runOnUiThread(() -> { | |
temperatureText.setText("水温: " + temperature); | |
waterLevelText.setText("水位: " + waterLevel); | |
}); | |
} | |
private void showModeSelectionDialog() { | |
AlertDialog.Builder builder = new AlertDialog.Builder(this); | |
builder.setTitle("选择模式"); | |
String[] modes = {"自动模式", "定时模式", "阈值设置模式"}; | |
builder.setItems(modes, (dialog, which) -> { | |
// 发送模式切换指令到蓝牙设备 | |
if (connectedThread != null) { | |
connectedThread.write((which + 1) + ""); // 假设用1,2,3表示不同模式 | |
} | |
}); | |
builder.show(); | |
} | |
private void showTimePickerDialog() { | |
// 创建时间选择器对话框 | |
TimePickerDialog timePickerDialog = new TimePickerDialog(this, | |
(view, hourOfDay, minute) -> { | |
// 发送定时时间设置指令到蓝牙设备 | |
if (connectedThread != null) { | |
connectedThread.write("T" + hourOfDay + ":" + minute); // 假设格式为T小时:分钟 | |
} | |
}, 12, 0, true); | |
timePickerDialog.show(); | |
} | |
private void showThresholdSettingDialog() { | |
AlertDialog.Builder builder = new AlertDialog.Builder(this); | |
builder.setTitle("设置水温阈值"); | |
View view = getLayoutInflater().inflate(R.layout.dialog_threshold_setting, null); | |
final EditText thresholdEdit = view.findViewById(R.id.threshold_edit); | |
builder.setView(view); | |
builder.setPositiveButton("确定", (dialog, which) -> { | |
String thresholdStr = thresholdEdit.getText().toString(); | |
if (!thresholdStr.isEmpty()) { | |
int threshold = Integer.parseInt(thresholdStr); | |
// 发送阈值设置指令到蓝牙设备 | |
if (connectedThread != null) { | |
connectedThread.write("S" + threshold); // 假设格式为S阈值 | |
} | |
} | |
}); | |
builder.setNegativeButton("取消", null); | |
builder.show(); | |
} | |
// 蓝牙连接相关线程(简化版) | |
private class ConnectThread extends Thread { | |
private final BluetoothSocket mmSocket; | |
private final BluetoothDevice mmDevice; | |
public ConnectThread(BluetoothDevice device) { | |
BluetoothSocket tmp = null; | |
mmDevice = device; | |
try { | |
tmp = device.createRfcommSocketToServiceRecord(MY_UUID); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
mmSocket = tmp; | |
} | |
public void run() { | |
bluetoothAdapter.cancelDiscovery(); | |
try { | |
mmSocket.connect(); | |
} catch (IOException connectException) { | |
try { | |
mmSocket.close(); | |
} catch (IOException closeException) { | |
e.printStackTrace(); | |
} | |
return; | |
} | |
connectedThread = new ConnectedThread(mmSocket); | |
connectedThread.start(); | |
} | |
public void cancel() { | |
try { | |
mmSocket.close(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
private class ConnectedThread extends Thread { | |
private final BluetoothSocket mmSocket; | |
private final InputStream mmInStream; | |
private final OutputStream mmOutStream; | |
public ConnectedThread(BluetoothSocket socket) { | |
mmSocket = socket; | |
InputStream tmpIn = null; | |
OutputStream tmpOut = null; | |
try { | |
tmpIn = socket.getInputStream(); | |
tmpOut = socket.getOutputStream(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
mmInStream = tmpIn; | |
mmOutStream = tmpOut; | |
} | |
public void run() { | |
byte[] buffer = new byte[1024]; | |
int bytes; | |
while (true) { | |
try { | |
bytes = mmInStream.read(buffer); | |
String receivedMessage = new String(buffer, 0, bytes); | |
// 解析接收到的数据并更新UI | |
// 实际应用中,这里需要根据数据格式进行解析 | |
if (receivedMessage.startsWith("T")) { | |
// 温度数据 | |
String temperature = receivedMessage.substring(1); | |
updateDisplay(temperature, waterLevelText.getText().toString().split(": ")[1]); | |
} else if (receivedMessage.startsWith("W")) { | |
// 水位数据 | |
String waterLevel = receivedMessage.substring(1); | |
updateDisplay(temperatureText.getText().toString().split(": ")[1], waterLevel); | |
} | |
} catch (IOException e) { | |
e.printStackTrace(); | |
break; | |
} | |
} | |
} | |
public void write(String message) { | |
byte[] bytes = message.getBytes(); | |
try { | |
mmOutStream.write(bytes); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
public void cancel() { | |
try { | |
mmSocket.close(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
// 其他必要的生命周期方法和蓝牙配对、连接等逻辑需要根据实际情况完善 | |
} |
xml
<!-- activity_main.xml --> | |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:tools="http://schemas.android.com/tools" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:orientation="vertical" | |
android:padding="16dp" | |
tools:context=".MainActivity"> | |
<TextView | |
android:id="@+id/temperature_text" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:text="水温: " | |
android:textSize="18sp" /> | |
<TextView | |
android:id="@+id/water_level_text" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_marginTop="8dp" | |
android:text="水位: " | |
android:textSize="18sp" /> | |
<Button | |
android:id="@+id/mode_button" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:layout_marginTop="16dp" | |
android:text="切换模式" /> | |
<Button | |
android:id="@+id/set_time_button" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:layout_marginTop="8dp" | |
android:text="设置定时时间" /> | |
<Button | |
android:id="@+id/set_threshold_button" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:layout_marginTop="8dp" | |
android:text="设置水温阈值" /> | |
</LinearLayout> |
xml
<!-- dialog_threshold_setting.xml --> | |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:orientation="vertical" | |
android:padding="16dp"> | |
<TextView | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:text="请输入水温阈值(°C):" | |
android:textSize="16sp" /> | |
<EditText | |
android:id="@+id/threshold_edit" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:inputType="number" /> | |
</LinearLayout> |
以上示例源码展示了手机APP的部分功能实现,包括界面布局、模式切换、定时时间设置、阈值设置以及蓝牙通信的基本框架。实际应用中,还需要根据具体的蓝牙协议和数据格式进行完善和优化。