在本节,我们要实现一个手机实时获取环境湿度的功能,并在手机上以曲线的形式显示湿度的波动。
将湿度传感器放在花盆中,就可以实时监测花盆的湿度了。
接下来分 单片机 和 调试器 两部分介绍。
一、单片机端的工作
1.1硬件连接
我使用的是AM2001型的湿度传感器,其有三根接线,黑色接地、红色接5V,黄色输出模拟信号,范围是0~3V,对应了0%和100%的湿度。因此我们只需要将其信号输出的引脚到单片机模拟输入的引脚即可。这里使用了PA0引脚,要使用STM32的模拟量采集功能需要配置ADC(模拟数字转换器)。
1.2湿度传感器(Humidity Sensor)代码
首先是初始化代码
void initHumiditySensor()
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
GPIO_InitStructure.GPIO_Pin= GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed= GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
ADC_InitStructure.ADC_ContinuousConvMode= ENABLE;
ADC_InitStructure.ADC_Mode= ADC_Mode_Independent;
ADC_InitStructure.ADC_DataAlign= ADC_DataAlign_Right;
ADC_InitStructure.ADC_ExternalTrigConv= ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_NbrOfChannel=1;
ADC_InitStructure.ADC_ScanConvMode= DISABLE;
ADC_Init(ADC1,&ADC_InitStructure);
RCC_ADCCLKConfig(RCC_PCLK2_Div8);
ADC_RegularChannelConfig(ADC1, ADC_Channel_0,1,
ADC_SampleTime_55Cycles5);
ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1))
{}
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1))
{}
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
这里使用了STM32的ADC1来采集湿度传感器的模拟信号。首先这是IO口PA0在AIN模式,然后配置ADC,ADC的具体配置就不多说了,需要确保里面的ADC_ContinuousConvMode= ENABLE,使之连续转换。
然后是获取测量值
比例系数,将ADC测量值转换为 0~100的百分比
float f = 100.0f/(4096*3/3.3f);
读取湿度信息,返回的数值为0~100,分辨度为0.1
float readHumidity(){
return ((int)((ADC1->DR)*f*10))*0.1f;
}
函数直接返回湿度的百分比。首先说一下“ f ”的意义,f 是为了将ADC采集的数值转化为实际的湿度值。 STM32的ADC最多只支持12位的AD转换,也就是说只能用0~4095这些数来表示输入的模拟量。简单来说就是 0对应0V,4096对应3.3V。而湿度计的模拟信号则定义为0~3V对应0~100。通过上述的式子可以得到一个比例值 f 将0~4095的数值转化为湿度百分比。
由于配置的ADC是持续转换的,因此直接读取ADC的DR寄存器就能获得模拟量的大小。
1.3单片机通信收发配置
首先在valuepack.h中定义要收发哪些变量,由于本次我们是要发送一个float类型的变量,所以配置如下:
// 根据实际需要的变量,定义数据包中 bool byte short int float 五种类型的数目
#define TX_BOOL_NUM 0
#define TX_BYTE_NUM 0
#define TX_SHORT_NUM 0
#define TX_INT_NUM 0
#define TX_FLOAT_NUM 1
配置好之后,编译器会自动为你生成一个带有float [1]数组的TxPack。
然后在main.c中使用这个TxPack
TxPack txpack;
int main(void){
initHumiditySensor();
initValuePack(115200);
while(1){
// 延时
for(int t=0;t<7200000;t++) { }
txpack.floats[0] = readHumidity();
sendValuePack(&txpack);
}
}
以上是所有主函数的代码,先初始化,然后进入主循环,延时一段时间后,读取湿度并将湿度传给txpack的floats[0],然后发送。之所以将延时定这么高,是因为这款湿度传感器的数据更新频率太低。很巧的是7200000此for循环实际和1秒时间相差不大,而STM32F103时钟是72000000Hz。
二、蓝牙调试器配置
创建工程步骤啥的在前面已经介绍完了,再贴图就没意思了。
主要看数据通道配置
添加了“湿度”这个变量,严格与之前在valuepack.h中定义的一致。
然后在“控件编辑”界面,添加需要的控件
选择上面的Y-T一维波形图,我也不知道当时怎么想的,起了这么绕口的名字。还是看图标,看图标就知道是显示波形的。
波形图控件最多支持链接6个变量,即最多同时显示六条曲线。默认是链接“接收-short”的变量,我们点击short,会出现下拉菜单,选择float,然后选择“湿度”。如此链接就成功了。
波形图太小了,使用右上方的平移、缩放和旋转 工具将控件调整为理想的布局。
然后添加一个能量槽,流程与波形图类似。也是链接“湿度”
只是在能量槽上下限参数设置时,设置其上下限为0~100。如下图
点击OK完成,然后添加一个文本,也是链接“湿度”。
最终效果如下
我觉得蓝牙调试器最迷人的地方就在于此,动动手指,不写一行代码,就可以得到一个专门为你的项目而设计的手机APP。
然后连接设备,开始运行就可以了。祝你玩得开心。
应用可以直接扫码下载: