개발자/Raspberry Pi

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

지구빵집 2014. 10. 2. 20:14
반응형


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 코드 추가할 예정


반응형