概述
HS3003是一種數字式溫濕度傳感器,可以測量環境中的溫度和濕度。讀取HS3003的數據需要連接傳感器到一個數據采集系統,一般是微處理器或者單片機。以下是一個簡單的讀取HS3003數據的概述:
連接電路:將HS3003傳感器連接到微處理器或單片機的GPIO引腳。需要注意HS3003的電氣特性,比如供電電壓和信號電平等。
發送命令:發送讀取溫濕度數據的命令到HS3003傳感器。具體的命令格式和通信協議需要參考HS3003的數據手冊。
接收數據:等待HS3003傳感器回應,并接收傳感器發送的數據。HS3003傳感器的數據一般是經過數字轉換后的二進制數據,需要解析成溫濕度值。
解析數據:將接收到的二進制數據解析成溫濕度值。具體的解析算法需要參考HS3003的數據手冊,一般涉及到位移、位運算、符號擴展等操作。
處理數據:對得到的溫濕度值進行處理,比如校準、濾波、顯示等。
循環讀取:根據需要循環執行步驟2到5,以實現連續讀取HS3003傳感器的溫濕度數據。 需要注意的是,HS3003傳感器的使用和讀取數據需要按照數據手冊的規范和建議操作,否則可能會導致數據精度降低、傳感器損壞等問題。
視頻教學
[https://www.bilibili.com/video/BV1th4y1R7of/]
csdn課程
csdn課程更加詳細。
[https://edu.csdn.net/course/detail/36131]
樣品申請
[https://www.wjx.top/vm/wBbmSFp.aspx#]
硬件準備
首先需要準備一個開發板,這里我準備的是芯片型號R7FAM2AD3CFP的開發板:
樣品申請
[https://www.wjx.top/vm/wBbmSFp.aspx#]
IIC配置
配置RA4M2的I2C接口,使其作為I2C master進行通信。 對于OLED的IIC配置,可以查看往期的博客。 查看HS3003說明書,最小電路圖如下所示。
由于需要讀取HS3003數據,需要使用IIC接口,這里使用PMOD2上的接口(P410和P411)。
點擊Stacks->New Stack->Connectivity -> I2C Master(r_sci_i2c)。
查看說明書可以得知,ISL29035的地址為0x44(1000100)。
設置IIC的配置。
R_SCI_I2C_Open()函數原型
R_SCI_I2C_Open()函數為執行IIC初始化,開啟配置如下所示。
/* Initialize the I2C module */
err = R_SCI_I2C_Open(&g_i2c0_ctrl, &g_i2c0_cfg);
/* Handle any errors. This function should be defined by the user. */
assert(FSP_SUCCESS == err);
R_SCI_I2C_Write()函數原型
R_SCI_I2C_Write()函數是向IIC設備中寫入數據,寫入格式如下所示。
err = R_SCI_I2C_Write(&g_i2c0_ctrl, &g_i2c_tx_buffer[0], I2C_BUFFER_SIZE_BYTES, false);
assert(FSP_SUCCESS == err);
R_SCI_I2C_Read()函數原型
R_SCI_I2C_Read()函數是向IIC設備中讀取數據,讀取格式如下所示。
err = R_SCI_I2C_Write(&g_i2c0_ctrl, &g_i2c_tx_buffer[0], I2C_BUFFER_SIZE_BYTES, false);
assert(FSP_SUCCESS == err);
sci_i2c_master_callback()回調函數
對于數據是否發送完畢,可以查看是否獲取到I2C_MASTER_EVENT_TX_COMPLETE字段。
/* Callback function */
i2c_master_event_t i2c_event1 = I2C_MASTER_EVENT_ABORTED;
void sci_i2c_master_callback0(i2c_master_callback_args_t *p_args)
{
/* TODO: add your own code here */
i2c_event1 = I2C_MASTER_EVENT_ABORTED;
if (NULL != p_args)
{
/* capture callback event for validating the i2c transfer event*/
i2c_event1 = p_args- >event;
}
}
HS3003寫數據
對于HS3003寫數據,手冊上的操作方式如下所示。 設備地址+操作地址+數據
初始化程序如下所示。
void Humiture_HS3003_writeRegister( int reg_address, uint8_t val)
{
uint8_t ii[2]={0x00,0x00};
ii[0] = reg_address;
ii[1] = val;
err = R_SCI_I2C_Write(&g_i2c0_ctrl, ii, 0x02, false);
assert(FSP_SUCCESS == err);
/* Since there is nothing else to do, block until Callback triggers*/
//while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms)
while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event1) && timeout_ms1 >0)
{
R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MICROSECONDS);
timeout_ms1--;
}
if (I2C_MASTER_EVENT_ABORTED == i2c_event1)
{
__BKPT(0);
}
/* Read data back from the I2C slave */
i2c_event1 = I2C_MASTER_EVENT_ABORTED;
timeout_ms1 = 100000;
}
HS3003讀數據
對于讀取數據,可以直接在發送地址后,進行讀取,當時需要注意再發送完地址后,要有等待時間。
讀取操作函數如下所示,先發送操作地址,在進行讀取,這里是一次讀取32位。
uint32_t Humiture_HS3003_readRegister32(uint8_t reg_address) {
uint32_t value;
uint8_t data[4];
timeout_ms1 = 100000;
/* Read data from I2C slave */
err = R_SCI_I2C_Read(&g_i2c0_ctrl, &data, 0x04, false);
assert(FSP_SUCCESS == err);
while ((I2C_MASTER_EVENT_RX_COMPLETE != i2c_event1) && timeout_ms1)
{
R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MILLISECONDS);
timeout_ms1--;
}
if (I2C_MASTER_EVENT_ABORTED == i2c_event1)
{
__BKPT(0);
}
i2c_event1 = I2C_MASTER_EVENT_ABORTED;
timeout_ms1 = 100000;
value=data[0];
value< <=8;
value|=data[1];
value< <=8;
value|=data[2];
value< <=8;
value|=data[3];
return value;
}
HS3003初始化
首先需要將HS3003進行喚醒,默認情況下是睡眠模式。 喚醒需要對Measurement Requests (MR)進行操作,MR命令用于將HS300x從休眠模式喚醒。通過發送7位從地址和第8位=0 (WRITE)來發起測量請求。
對于不同精度的數據讀取,等待時間是不同的。
對于等待的時間,可以參考下圖紅框的數據。
HS3003讀取溫濕度
對于讀取數據,可以直接在發送地址后,進行讀取,當時需要注意再發送完地址后,要有等待時間。
讀取操作函數如下所示,先發送操作地址,在進行讀取。
void Humiture_HS3003_init(void)
{
Humiture_HS3003_writeRegister(HS300X_ADR,0);
}
//讀取原始的數據
uint32_t Humiture_HS3003_ReadData_Raw(uint8_t resolution )
{
uint8_t rx_buf[ 4 ];
uint32_t data=0;
Humiture_HS3003_init();//喚醒
//8bit- >1.2ms
//10bit- >2.72ms
//12bit- >9.10ms
//14bit- >33.90ms
if(resolution==8)
R_BSP_SoftwareDelay(1200U, BSP_DELAY_UNITS_MICROSECONDS);
else if(resolution==10)
R_BSP_SoftwareDelay(2720U, BSP_DELAY_UNITS_MICROSECONDS);
else if(resolution==12)
R_BSP_SoftwareDelay(9100U, BSP_DELAY_UNITS_MICROSECONDS);
else
R_BSP_SoftwareDelay(34U, BSP_DELAY_UNITS_MILLISECONDS);
data=Humiture_HS3003_readRegister32(HS300X_ADR);
return data;
}
對于讀取的數據,需要進行處理。 濕度在后兩個字節的15-2位,溫度在前2個字節的13-0位。
對于原始的數據,要對他進行處理。
Data=Humiture_HS3003_ReadData_Raw(14);
Temp = (float)( (Data & 0xFFFF) > > 2);//只要低十六位
Temp = Temp*HS300X_TEMP_MULTY*165-40;//HS300X_TEMP_MULTY- >0.00006163516(1/(2^14-1) )
Humidity = (float)( (Data > > 16) &0x3FFF );//只要高十六位,且最高2位不要
Humidity = Humidity*HS300X_HUMD_MULTY*100;//HS300X_HUMD_MULTY- >0.00006163516(1/(2^14-1) )
實現效果
正常顯示數據。
同時串口也可以打印數據。
主程序
#include "hal_data.h"
#include < stdio.h >
#include "Humiture_HS3003.h"
#include "oled.h"
#include "bmp.h"
FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER
fsp_err_t err = FSP_SUCCESS;
volatile bool uart_send_complete_flag = false;
/* Callback function */
void user_uart_callback(uart_callback_args_t *p_args)
{
/* TODO: add your own code here */
if(p_args- >event == UART_EVENT_TX_COMPLETE)
{
uart_send_complete_flag = true;
}
}
#ifdef __GNUC__ //串口重定向
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
err = R_SCI_UART_Write(&g_uart9_ctrl, (uint8_t *)&ch, 1);
if(FSP_SUCCESS != err) __BKPT();
while(uart_send_complete_flag == false){}
uart_send_complete_flag = false;
return ch;
}
int _write(int fd,char *pBuffer,int size)
{
for(int i=0;i< size;i++)
{
__io_putchar(*pBuffer++);
}
return size;
}
/* Callback function */
i2c_master_event_t i2c_event1 = I2C_MASTER_EVENT_ABORTED;
void sci_i2c_master_callback0(i2c_master_callback_args_t *p_args)
{
/* TODO: add your own code here */
i2c_event1 = I2C_MASTER_EVENT_ABORTED;
if (NULL != p_args)
{
/* capture callback event for validating the i2c transfer event*/
i2c_event1 = p_args- >event;
}
}
/* Callback function */
i2c_master_event_t i2c_event = I2C_MASTER_EVENT_ABORTED;
void sci_i2c_master_callback(i2c_master_callback_args_t *p_args)
{
i2c_event = I2C_MASTER_EVENT_ABORTED;
if (NULL != p_args)
{
/* capture callback event for validating the i2c transfer event*/
i2c_event = p_args- >event;
}
}
uint32_t timeout_ms1 = 100000;
uint32_t timeout_ms = 100000;
float Temp=0.0f;
float Humidity=0.0f;
uint32_t Data=0;//溫濕度原始數據
/*******************************************************************************************************************//**
* main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used. This function
* is called by main() when no RTOS is used.
**********************************************************************************************************************/
void hal_entry(void)
{
/* TODO: add your own code here */
/* Initialize the I2C module */
err = R_SCI_I2C_Open(&g_i2c3_ctrl, &g_i2c3_cfg);
/* Handle any errors. This function should be defined by the user. */
assert(FSP_SUCCESS == err);
OLED_Init(); //初始化OLED
OLED_Clear() ;
OLED_ShowCHinese(0,0,0);//記
OLED_ShowCHinese(16,0,1);//帖
OLED_ShowString(0,2,"Temp:",16);
OLED_ShowString(0,4,"Humidity:",16);
/* Initialize the I2C module */
err = R_SCI_I2C_Open(&g_i2c0_ctrl, &g_i2c0_cfg);
/* Handle any errors. This function should be defined by the user. */
assert(FSP_SUCCESS == err);
Humiture_HS3003_init();
/* Open the transfer instance with initial configuration. */
fsp_err_t err = R_SCI_UART_Open(&g_uart9_ctrl, &g_uart9_cfg);
assert(FSP_SUCCESS == err);
printf("hello world!n");
while(1)
{
Data=Humiture_HS3003_ReadData_Raw(14);
Temp = (float)( (Data & 0xFFFF) > > 2);//只要低十六位
Temp = Temp*HS300X_TEMP_MULTY*165-40;//HS300X_TEMP_MULTY- >0.00006163516(1/(2^14-1) )
Humidity = (float)( (Data > > 16) &0x3FFF );//只要高十六位,且最高2位不要
Humidity = Humidity*HS300X_HUMD_MULTY*100;//HS300X_HUMD_MULTY- >0.00006163516(1/(2^14-1) )
OLED_Clear() ;
OLED_ShowCHinese(0,0,0);//記
OLED_ShowCHinese(16,0,1);//帖
OLED_ShowString(0,2,"Temp:",16);
OLED_ShowString(0,4,"Humidity:",16);
if(Temp< 10 && Temp >=0)//0<=Temp< 10
{
OLED_ShowNum(48,2,(int)(Temp),1,16);//顯示Temp整數
OLED_ShowString(56,2,".",16);
OLED_ShowNum(64,2,(int)(Temp*100) - ( ((int)Temp) *100),1,16);//顯示Temp小數
if(( (int)(Temp*100) - ( ((int)Temp) *100) ) < 10 )
OLED_ShowString(64,2,"0",16);
}
else if (Temp >=10 && Temp< 100)//10<=Temp< 100
{
OLED_ShowNum(48,2,(int)(Temp),2,16);//顯示Temp整數
OLED_ShowString(64,2,".",16);
OLED_ShowNum(72,2,(int)(Temp*100) - ( ((int)Temp) *100),2,16);//顯示Temp小數
if(( (int)(Temp*100) - ( ((int)Temp) *100) ) < 10 )
OLED_ShowString(72,2,"0",16);
}
else if (Temp >=100 && Temp< 1000)//100<=Temp< 1000
{
OLED_ShowNum(48,2,(int)(Temp),3,16);//顯示Temp整數
OLED_ShowString(72,2,".",16);
OLED_ShowNum(80,2,(int)(Temp*100) - ( ((int)Temp) *100),2,16);//顯示Temp小數
if(( (int)(Temp*100) - ( ((int)Temp) *100) ) < 10 )
OLED_ShowString(80,2,"0",16);
}
if(Humidity< 10)//0<=Humidity< 10
{
OLED_ShowNum(72,4,(int)(Humidity),1,16);//顯示Humidity整數
OLED_ShowString(80,4,".",16);
OLED_ShowNum(88,4,(int)(Humidity*100) - ( ((int)Humidity) *100),2,16);//顯示Temp小數
if(( (int)(Humidity*100) - ( ((int)Humidity) *100) ) < 10 )
OLED_ShowString(88,4,"0",16);
}
else if(Humidity >10 && Humidity< 100)
{
OLED_ShowNum(72,4,(int)(Humidity),2,16);//顯示Humidity整數
OLED_ShowString(88,4,".",16);
OLED_ShowNum(96,4,(int)(Humidity*100) - ( ((int)Humidity) *100),2,16);//顯示Temp小數
if(( (int)(Humidity*100) - ( ((int)Humidity) *100) ) < 10 )
OLED_ShowString(96,4,"0",16);
}
printf("Temp=%.2f,Humidity=%.2fn",Temp,Humidity);
R_BSP_SoftwareDelay(1000U, BSP_DELAY_UNITS_MILLISECONDS);
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
Humiture_HS3003.c
/*
* Humiture_HS3003.c
*
* Created on: 2023年2月19日
* Author: a8456
* 交流群:615061293
*/
#include "hal_data.h"
#include "Humiture_HS3003.h"
extern fsp_err_t err;
extern int timeout_ms1;
extern i2c_master_event_t i2c_event1 ;
uint32_t Humiture_HS3003_readRegister32(uint8_t reg_address) {
uint32_t value;
uint8_t data[4];
timeout_ms1 = 100000;
/* Read data from I2C slave */
err = R_SCI_I2C_Read(&g_i2c0_ctrl, &data, 0x04, false);
assert(FSP_SUCCESS == err);
while ((I2C_MASTER_EVENT_RX_COMPLETE != i2c_event1) && timeout_ms1)
{
R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MILLISECONDS);
timeout_ms1--;
}
if (I2C_MASTER_EVENT_ABORTED == i2c_event1)
{
__BKPT(0);
}
i2c_event1 = I2C_MASTER_EVENT_ABORTED;
timeout_ms1 = 100000;
value=data[0];
value< <=8;
value|=data[1];
value< <=8;
value|=data[2];
value< <=8;
value|=data[3];
return value;
}
void Humiture_HS3003_writeRegister( uint8_t reg_address, uint8_t *buffer, uint8_t len)
{
err = R_SCI_I2C_Write(&g_i2c0_ctrl, buffer, len, false);
assert(FSP_SUCCESS == err);
/* Since there is nothing else to do, block until Callback triggers*/
//while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms)
while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event1) && timeout_ms1 >0)
{
R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MICROSECONDS);
timeout_ms1--;
}
if (I2C_MASTER_EVENT_ABORTED == i2c_event1)
{
__BKPT(0);
}
/* Read data back from the I2C slave */
i2c_event1 = I2C_MASTER_EVENT_ABORTED;
timeout_ms1 = 100000;
}
void Humiture_HS3003_init(void)
{
Humiture_HS3003_writeRegister(HS300X_ADR,NULL,0);
}
//讀取原始的數據
uint32_t Humiture_HS3003_ReadData_Raw(uint8_t resolution )
{
uint8_t rx_buf[ 4 ];
uint32_t data=0;
Humiture_HS3003_init();//喚醒
//8bit- >1.2ms
//10bit- >2.72ms
//12bit- >9.10ms
//14bit- >33.90ms
if(resolution==8)
R_BSP_SoftwareDelay(1200U, BSP_DELAY_UNITS_MICROSECONDS);
else if(resolution==10)
R_BSP_SoftwareDelay(2720U, BSP_DELAY_UNITS_MICROSECONDS);
else if(resolution==12)
R_BSP_SoftwareDelay(9100U, BSP_DELAY_UNITS_MICROSECONDS);
else
R_BSP_SoftwareDelay(34U, BSP_DELAY_UNITS_MILLISECONDS);
data=Humiture_HS3003_readRegister32(HS300X_ADR);
return data;
}
Humiture_HS3003.h
/*
* Humiture_HS3003.h
*
* Created on: 2023年2月19日
* Author: a8456
* 交流群:615061293
*/
#ifndef HUMITURE_HS3003_H_
#define HUMITURE_HS3003_H_
#define HS300X_ADR 0x44
#define HS300X_HUMD_MULTY 0.00006163516
#define HS300X_TEMP_MULTY 0.00006163516
//uint8_t HuMIture_HS3003_readRegister8(uint8_t reg_address);
uint32_t Humiture_HS3003_readRegister32(uint8_t reg_address);
void Humiture_HS3003_writeRegister( uint8_t reg_address, uint8_t *buffer, uint8_t len);
void Humiture_HS3003_init(void);
uint32_t Humiture_HS3003_ReadData_Raw(uint8_t resolution);
#endif /* HUMITURE_HS3003_H_ */
審核編輯:湯梓紅
-
傳感器
+關注
關注
2560文章
52118瀏覽量
761237 -
led
+關注
關注
242文章
23596瀏覽量
668628 -
OLED
+關注
關注
119文章
6250瀏覽量
226362 -
串口
+關注
關注
14文章
1579瀏覽量
78274 -
RA4M2
+關注
關注
2文章
20瀏覽量
1026
發布評論請先 登錄
相關推薦
評論