文章目录
一、传感器简介
模块基于电容式检测原理,通过测量土壤介电常数变化来判断土壤湿度。相比传统电阻式传感器,具有不易腐蚀、使用寿命长、抗干扰能力强的特点。模块内部采用 NE555 振荡电路、电容感应探头,输出为模拟电压信号,可直接接入 ADC 采集


二、引脚功能
| 引脚 | 功能 |
|---|---|
| GND | 电源地 |
| 5V | 5V供电引脚,也可接3.3V,输出会低0.1V |
| OUT | 模拟电压输出引脚,输出范围1-2V左右,对应湿度100%-0% |
三、采集程序
本次实验采用的开发板分别是 arduino uno 、STM32F103RC、STC89C52
arduino uno、STM32F103 有片内 AD 资源,可直接采集土壤湿度传感器输出的模拟电压; STC89C52 无片内AD需外挂一个ADC模块,采用的是ADS1115,相关教程可参考:51 驱动 ADS1115 AD采集
arduino
.ino
c
const int sensorPin = A0;
const float VREF = 5.0;
const int ADC_RES = 1023;
void setup() {
Serial.begin(9600);
}
void loop() {
int adcValue = analogRead(sensorPin);
float voltage = adcValue * (VREF / ADC_RES);
// 限制1~2.05V范围
if (voltage > 2.05) voltage = 2.05;
if (voltage < 1.0) voltage = 1.0;
float humidity = (2.05 - voltage) * 100.0;
Serial.print("ADC: ");
Serial.print(adcValue);
Serial.print(" Voltage: ");
Serial.print(voltage, 3);
Serial.print(" V Humidity: ");
Serial.print(humidity, 1);
Serial.println(" %");
delay(1000);
}
STM32
AD.C
c
#include "stm32f10x.h" // Device header
/**
* 函 数:AD初始化
* 参 数:无
* 返 回 值:无
*/
void AD_Init(void)
{
/*开启时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //开启ADC1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟
/*设置ADC时钟*/
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //选择时钟6分频,ADCCLK = 72MHz / 6 = 12MHz
/*GPIO初始化*/
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure); //将PA0引脚初始化为模拟输入
/*规则组通道配置*/
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5); //规则组序列1的位置,配置为通道0
/*ADC初始化*/
ADC_InitTypeDef ADC_InitStructure; //定义结构体变量
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //模式,选择独立模式,即单独使用ADC1
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据对齐,选择右对齐
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //外部触发,使用软件触发,不需要外部触发
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //连续转换,失能,每转换一次规则组序列后停止
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //扫描模式,失能,只转换规则组的序列1这一个位置
ADC_InitStructure.ADC_NbrOfChannel = 1; //通道数,为1,仅在扫描模式下,才需要指定大于1的数,在非扫描模式下,只能是1
ADC_Init(ADC1, &ADC_InitStructure); //将结构体变量交给ADC_Init,配置ADC1
/*ADC使能*/
ADC_Cmd(ADC1, ENABLE); //使能ADC1,ADC开始运行
/*ADC校准*/
ADC_ResetCalibration(ADC1); //固定流程,内部有电路会自动执行校准
while (ADC_GetResetCalibrationStatus(ADC1) == SET);
ADC_StartCalibration(ADC1);
while (ADC_GetCalibrationStatus(ADC1) == SET);
}
/**
* 函 数:获取AD转换的值
* 参 数:无
* 返 回 值:AD转换的值,范围:0~4095
*/
uint16_t AD_GetValue(void)
{
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //软件触发AD转换一次
while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); //等待EOC标志位,即等待AD转换结束
return ADC_GetConversionValue(ADC1); //读数据寄存器,得到AD转换的结果
}
main.C
c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"
#include "sys.h"
#include "usart.h"
uint16_t ADValue; //定义AD值变量
float Voltage; //定义电压变量
float humidity;
char HumD[10] = {0};
int main(void)
{
SystemInit();
AD_Init(); //AD初始化
NVIC_Configuration();
uart_init(9600);
while (1)
{
ADValue = AD_GetValue(); //获取AD转换的值
Voltage = (float)ADValue / 4095 * 3.3; //将AD值线性变换到0~3.3的范围,表示电压
if(Voltage > 2.0)
{
Voltage = 2.0;
}
if(Voltage < 1.0)
{
Voltage = 1.0;
}
humidity = (2.0 - Voltage) * 100.0;
sprintf(HumD,"RH:%0.1F",humidity);
Usart1_SandTXString(HumD);
Delay_ms(500); //延时100ms,手动增加一些转换的间隔时间
}
}
C51
main.C
c
#include <STC89C5xRC.H>
#include <IIC.H>
#include <uart.H>
#include <ADS1115.H>
#include <delay.H>
//整形数据转字符数组
void IntToString(unsigned char *str,unsigned int dat)//str 存放字符的数组,dat 整形数据
{
unsigned char i = 0;
unsigned int buf[8];
do { //先转换成 低位在前的十进制数组 将低位高位互换
buf[i++] = dat % 10;
dat /= 10;
} while (dat > 0);
while (i-- > 0) //将数组值转换为 ASCII 码反向拷贝到接收指针上
{
*str++ = buf[i] + '0';
}
*str = '\0';
}
void main()
{
float Voltage=0,humidity;
unsigned char arr[8];
char * P = arr;
uart_init();//波特率2400
ADS1115_Write();
Delay_x_ms(1000);
while(1)
{
Voltage = ADS1115_Read();
if(Voltage > 2.0){Voltage = 2.0;}
if(Voltage < 1.0){Voltage = 1.0;}
humidity = (2.0 - Voltage) * 100.0;
IntToString(P,humidity);
UART_Send(P);
UART_SendByte('.');
humidity = (humidity - (int)humidity)*10;//取小数
IntToString(P,humidity);
UART_Send(P);
UART_Send("%");
Delay_x_ms(500);
}
}
四、实验现象
---------------------------------------------------传感器接线--------------------------------------------------
C51 :
ADS1115_SCL --- P2^0
ADS1115_SDA --- P2^1
传感器_OUT --- ADS1115_AIN0
STM32 :
传感器_OUT --- PA0
arduino :
传感器_OUT --- A0
开发板串口输出如下:



以上内容个人理解,如有不正欢迎指正,需要资料及工程可留言邮箱