본문 바로가기

개발자/Raspberry Pi

HT-01SV 온습도 센서 구현 코드들

반응형


HT-01SV 온습도 센서 구현 코드들


HT-01SV는 정젂용량 방식의 습도센서 와 밴드갭 온도센서의 일체형 센서로 디지털 측정값을 젂압으로 변환하여 출력하도록 구성한, 개별적으로 모두 보정이 되어 출하되는 뛰어난 성능의 온습도 겸용 센서입니다. 


특징


- 상대습도 및 온도 측정 센서

- 젂압 출력 (관련 수식 참조)

- 뛰어난 장기 안정성

- 저젂력 소모

- 작은 사이즈 (SMD type)


적용 분야


- HVAC, 공장자동화, 데이터 로깅, 가젂, 자동차, 기상장비, 가습,제습기, 의료분야 등..


자세한 센서 사양은 아래의 두개 문서 참조 - 거의 동일



HT-01xx manual.pdf



온습도센서_HT01SV.pdf



그리고 아래의 코드를 참조하시면 되는데 코드를 찾아 본 이유는 ADC 로 읽은 코드를 어떻게 처리하는가가 조금 어려운 부분이다. 12Bit 로 읽은 A/D 컨버젼하여 읽은 데이터를 센서 출력값에 해당하는 Voltage 값으로 변환하여 데이타북에 명시된 공식으로 구하면 여하튼 되는 과정으로 확인하였다.


아래 개발 코드는 좀더 보완하시길 바랍니다.


기능 : 온도 습도 조도 값을 출력~ 


#include <stdio.h>
#include <string.h>
#include <errno.h>

#include <wiringPi.h>
#include <wiringPiSPI.h>

#define CS_MCP3208 8 //GPIO 8

#define SPI_CHANNEL 0
#define SPI_SPEED 1000000 //1Mhz

// spi communication with Rpi  and get sensor data

int read_mcp3208_adc(unsigned char adcChannel)
{
	unsigned char buff[3];
	int adcValue = 0;
	
	buff[0] = 0x06 | ((adcChannel & 0x07) >> 2);
	buff[1] = ((adcChannel & 0x07) << 6);
	buff[2] = 0x00;
	
	digitalWrite(CS_MCP3208, 0);
	wiringPiSPIDataRW(SPI_CHANNEL, buff, 3);
	
	buff[1] = 0x0f & buff[1];
	adcValue = (buff[1] << 8 ) | buff[2];
	
	digitalWrite(CS_MCP3208, 1);
	
	return adcValue;
}

int main(void)
{
	unsigned char adcChannel_humi = 0;
	unsigned char adcChannel_temp = 1;
	unsigned char adcChannel_light = 2;
	
	int adcValue_humi = 0;
	int adcValue_temp = 0;
	int adcValue_light = 0;
	
	float vout_ofhumi;
	float vout_oftemp;
	float percentrh = 0;
	float supsiondo = 0;
	
	int ret = system("gpio load spi");
	
	if(wiringPiSetupGpio() == -1)
	{
		fprintf(stdout, "Unable to start wiringPi :%s\n", strerror(errno));
		return 1;
	}
	
	if(wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1)
	{
		fprintf(stdout, "wiringPiSPISetup Failed :%s\n", strerror(errno));
		return 1;
	}
	
	pinMode(CS_MCP3208, OUTPUT);
	
	while(1)
	{
		adcValue_humi = read_mcp3208_adc(adcChannel_humi);
		adcValue_temp = read_mcp3208_adc(adcChannel_temp);
		adcValue_light = read_mcp3208_adc(adcChannel_light);

		vout_ofhumi = (3.3f * (float)adcValue_humi)/4095.0f;
		vout_oftemp = (3.3f * (float)adcValue_temp)/4095.0f;
		
		//vout_ofhumi = adcValue_humi;
		//vout_oftemp = adcValue_temp;
		
		printf("volt of humid = %g  volt of temp = %g\n", vout_ofhumi, vout_oftemp);

		percentrh = vout_ofhumi / (3.3f / 100.0);
		supsiondo = vout_oftemp / (3.3f /165) - 40.0;
		 
		//printf("Humidity = %u   temperature =  %u\n", adcValue_humi, adcValue_temp);
		printf("Humidity  = %f Temperature = %f  light = %d\n", percentrh, supsiondo, adcValue_light);
		
		delay(1000);

	}
	return 0;

}


아래 코드는 입력 인자에 따라 각기 다른 값 실행은 rpiADV 0 rpiADC 2 이런식으로 실행

#include <stdio.h> #include <string.h> #include <stdlib.h> #include <errno.h> #include <wiringPi.h> #include <wiringPiSPI.h> #define CS_MCP3208 8 //GPIO 8 #define SPI_CHANNEL 0 #define SPI_SPEED 1000000 //1Mhz #define false 0 // spi communication with Rpi and get sensor data int read_mcp3208_adc(unsigned char adcChannel) { unsigned char buff[3]; int adcValue = 0; buff[0] = 0x06 | ((adcChannel & 0x07) >> 2); buff[1] = ((adcChannel & 0x07) << 6); buff[2] = 0x00; digitalWrite(CS_MCP3208, 0); // Low : CS activelOW wiringPiSPIDataRW(SPI_CHANNEL, buff, 3); buff[1] = 0x0f & buff[1]; adcValue = (buff[1] << 8 ) | buff[2]; digitalWrite(CS_MCP3208, 1); return adcValue; } int main(int argc, char *argv[]) { int adcChannel = 0; int adcValue = 0; float temptemp = 0.0; float temphumi = 0.0; int ret = system("gpio load spi"); //System command if(argc == 2) { adcChannel = atoi(argv[1]); if((adcChannel >= 0 && adcChannel < 8) == false) { printf("Command error : ch = 0~7\n"); return -1; } } else { printf("Command error: rpiADC channel\n"); return -1; } if(wiringPiSetupGpio() == -1) { fprintf(stdout, "Unable to start wiringPi :%s\n", strerror(errno)); return 1; } if(wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) { fprintf(stdout, "wiringPiSPISetup Failed :%s\n", strerror(errno)); return 1; } pinMode(CS_MCP3208, OUTPUT); if(adcChannel == 0) { adcValue = read_mcp3208_adc(0); //Humidity sensor temptemp = (3.3f * (float)adcValue)/4095.0f; adcValue = temptemp / (3.3f / 100.0); } else if(adcChannel == 1) { adcValue = read_mcp3208_adc(1); //Temperature sensor temphumi = (3.3f * (float)adcValue)/4095.0f; adcValue = temphumi / (3.3f /165) - 40.0; } else if(adcChannel == 2) { adcValue = read_mcp3208_adc(2); //Moisture sensor } else adcValue = 0; printf("%d", adcValue); return adcValue; }

아래 코드는 다른데서 가져온것 : 헤더 퍼일


/* 
 * File:   ht01sv.h
 * Author: Administrator
 *
 * Created on May 26, 2014, 1:47 PM
 */

#ifndef HT01SV_H
#define	HT01SV_H

#ifdef	__cplusplus
extern "C" {
#endif

void initHT01SV();
void freeHT01SV();
void CalcSensorData(float *temp, float *humi);


#ifdef	__cplusplus
}
#endif

#endif	/* HT01SV_H */


아래는 C 파일



/* 
 * File:   ht01sv.c
 * Author: j.soobin@gmail.com   
 *
 * Created on May 26, 2014, 2:17 PM
 */

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <errno.h> 
#include <sched.h>

#include "./BBBio_lib/BBBiolib.h"
/* ------------------------------------------------------------ */
#define SENSOR_BUFFER_SIZE	100
#define SENSOR_SAMPLE_RATE	100
/* ----------------------------------------------------------- */
unsigned int buffer1[SENSOR_BUFFER_SIZE] ={0};
unsigned int buffer2[SENSOR_BUFFER_SIZE] ={0};

void initHT01SV(){
	//iolib_setdir(8,12, BBBIO_DIR_IN);
        
        const int clk_div = 1;
	const int open_dly = 0;
	const int sample_dly = 1;

	BBBIO_ADCTSC_module_ctrl(BBBIO_ADC_WORK_MODE_BUSY_POLLING, clk_div);
	BBBIO_ADCTSC_channel_ctrl(BBBIO_ADC_AIN4, BBBIO_ADC_STEP_MODE_SW_CONTINUOUS, open_dly, sample_dly, BBBIO_ADC_STEP_AVG_1, buffer1, SENSOR_BUFFER_SIZE);
	BBBIO_ADCTSC_channel_ctrl(BBBIO_ADC_AIN6, BBBIO_ADC_STEP_MODE_SW_CONTINUOUS, open_dly, sample_dly, BBBIO_ADC_STEP_AVG_1, buffer2, SENSOR_BUFFER_SIZE);

        /* fetch data from ADC */
	//printf("sample count %d\n",i);

	BBBIO_ADCTSC_channel_enable(BBBIO_ADC_AIN4);
	BBBIO_ADCTSC_channel_enable(BBBIO_ADC_AIN6);
}

void freeHT01SV(){
    iolib_free();
}

/**
 * Calc Sensor Data
 * @param temp temperature data
 * @param humi humidity data
 */
void CalcSensorData(float *temp, float *humi){
        int i ,j;
        const int fetchsize = 10;
	/* BBBIOlib init*/
	BBBIO_ADCTSC_work(fetchsize);

	/* using ADC_CALC toolkit to decide the ADC module argument .
	 *
	 *	#./ADC_CALC -f 44100 -t 30
	 *
	 *	Suggest Solution :
	 *		Clock Divider : 34 ,    Open Dly : 1 ,  Sample Average : 1 ,    Sample Dly : 1
	 */
		
	float temporature;
	float humidity;
	int tsum=0;
	int hsum=0;
	/* **********************************************************/
	// Add your Socket transmit function in this block
	for(j=0; j<fetchsize; j++){
		tsum += buffer1[j];
		hsum += buffer2[j];
	}
	/* ************************************************************ */

	temporature = ((float)(tsum/fetchsize) / 4095.0f) * 1.8f;
	humidity = ((float)(hsum/fetchsize) / 4095.0f) * 1.8f;

	temporature = temporature / (3.3f / 165) - 40;
	humidity = humidity / (3.3f / 100);

	//printf("temp = %f, humidity = %f\n",temporature,humidity);
        
        *temp = temporature;
        *humi = humidity;
}

끝~~ AVR 코드 추가할 예정


반응형

캐어랩 고객 지원

취업, 창업의 막막함, 외주 관리, 제품 부재!

당신의 고민은 무엇입니까? 현실과 동떨어진 교육, 실패만 반복하는 외주 계약, 아이디어는 있지만 구현할 기술이 없는 막막함.

우리는 알고 있습니다. 문제의 원인은 '명확한 학습, 실전 경험과 신뢰할 수 있는 기술력의 부재'에서 시작됩니다.

이제 고민을 멈추고, 캐어랩을 만나세요!

코딩(펌웨어), 전자부품과 디지털 회로설계, PCB 설계 제작, 고객(시장/수출) 발굴과 마케팅 전략으로 당신을 지원합니다.

제품 설계의 고수는 성공이 만든 게 아니라 실패가 만듭니다. 아이디어를 양산 가능한 제품으로!

귀사의 제품을 만드세요. 교육과 개발 실적으로 신뢰할 수 있는 파트너를 확보하세요.

지난 30년 여정, 캐어랩이 얻은 모든 것을 함께 나누고 싶습니다.

카카오 채널 추가하기

카톡 채팅방에서 무엇이든 물어보세요

당신의 성공을 위해 캐어랩과 함께 하세요.

캐어랩 온라인 채널 바로가기

캐어랩