๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

SW/Jetson nano & Raspberry Pi

RaspberryPi SenseHAT + HTS221 (์˜จ์Šต๋„์„ผ์„œ)

SenseHAT

์ผ๋‹จ SenseHAT๋Š” ์ด๋ ‡๊ฒŒ ๋ผ์ฆˆ๋ฒ ๋ฆฌํŒŒ์ด์— ์–น์–ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์นœ๊ตฌ๋‹ค.

์ถ• ๋†’์ด๊ฐ€ ์ผ์ •ํ•˜๊ฒŒ ๋”ฑ ๋งž์•„์„œ ์•ˆ์ •์ ์œผ๋กœ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ „์›์„ ์ธ๊ฐ€ํ•˜๋Š” ์ˆœ๊ฐ„ LED๋“ค์ด ๋ฐ˜์ง ์ผœ์ ธ์„œ ์„ฌ๊ด‘ํƒ„์„ ์—ฐ์ƒ์ผ€ํ•˜์ง€๋งŒ ์ดํ›„์—” ์˜ˆ์˜์žฅํ•˜๊ฒŒ ๋“ค์–ด์˜จ๋‹ค.

 

HTS221๋กœ๋ถ€ํ„ฐ ์˜จ์Šต๋„๋ฅผ ์ฝ์–ด๋‚ด๊ธฐ ์œ„ํ•ด์„  ๋ฐ์ดํ„ฐ์‹œํŠธ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

 

control register๋กœ ์ œ์–ดํ•˜๊ณ  ๋ฐ์ดํ„ฐ๊ฐ’๋„ I2C๋ฅผ ํ†ตํ•ด register๋ฅผ ์ฝ์–ด๋‚ด๋Š” ๋ฐฉ์‹์œผ๋กœ ํ•œ๋‹ค.

 

์˜จ๋„์™€ ์Šต๋„๋ฅผ ์ฝ์–ด๋‚ด๋Š” ๋ฐฉ์‹์€ ์•„๋‚ด์™€ ๊ฐ™๋‹ค. ๋‘ ์‚ฌ์ง„ ๋ชจ๋‘ HTS221 datasheet์—์„œ ์ผ๋ถ€ ๋ฐœ์ทŒํ•œ ์‚ฌ์ง„์ด๋‹ค.

 

HTS221 ์˜จ๋„๊ฐ’ ์ฝ๊ธฐ
HTS221 ์Šต๋„๊ฐ’ ์ฝ๊ธฐ

๊ฐ’์„ ๊ทธ๋ƒฅ ์ฝ์–ด๋‚ด๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ x์ขŒํ‘œ๊ฐ’ ๋‘๊ฐœ, ๊ทธ์— ์ƒ์‘ํ•˜๋Š” y์ขŒํ‘œ๊ฐ’ ๋‘๊ฐœ๋ฅผ ์ฝ์€ ํ›„, ๋‘ ์ ์„ ์ง€๋‚˜๋Š” ์ง์„ ์— ๋Œ€ํ•œ ๋ฐฉ์ •์‹์„ ํ†ตํ•ด ๊ฐ’์„ ์‹ค์ œ ์„ผ์„œ๊ฐ€ ์ฝ์€ ๊ฐ’์„ ๊ณ„์‚ฐํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

 

๋ฌธ์ œ๋Š” ์ด ๊ณ„์‚ฐ์„ ์ „๋ถ€ ์ฝ”๋”ฉ์œผ๋กœ ๊ฐˆ์•„ ๋„ฃ์–ด์•ผํ•œ๋‹ค๋Š” ์ ์ด๋‹ค.

 

๋ ˆ์ง€์Šคํ„ฐ์— ์ €์žฅ๋œ x,y ์ขŒํ‘œ๊ฐ’ ๋‘์„ธํŠธ๋Š” ํ˜„์žฌ ์˜จ์Šต๋„์— ๊ด€๋ จ์—†์ด ์ƒ์ˆ˜๊ฐ’์„ ์ง€๋‹ˆ๋Š” ๋“ฏ ๋ณด์ธ๋‹ค.

์•„๋งˆ ์„ผ์„œ ๋‚ด์— ๋‚ด์žฅ๋œ ์‚ฐ์ˆ ์—ฐ์‚ฐ์žฅ์น˜๊ฐ€ ์—†์ด๊ธฐ์— ์ด๋ ‡๊ฒŒ ์†Œํ”„ํŠธ์›จ์–ด์ ์œผ๋กœ ์‚ฐ์ˆ ์ •๋ณด๋ฅผ ์ฒ˜๋ฆฌํ•˜๋„๋ก ํ•˜๋Š” ๋“ฏ ํ•˜๋‹ค.

HTS221์˜ ์˜จ์Šต๋„ ์ฝ๊ธฐ

์„ผ์„œ์˜ ๊ฐ ๋ ˆ์ง€์Šคํ„ฐ๋Š” I2Cํ†ต์‹ ์œผ๋กœ ํ•˜๊ธฐ์—, ์ฝ์–ด๋‚ด๋Š” ๋ฐ์ดํ„ฐ๋ฅผ 8-bit์”ฉ ๋Š์–ด ์ฝ์–ด๋‚ด์•ผ ํ•˜๋Š”๋ฐ, ์‹ค์ œ๋กœ ์„ผ์„œ๊ฐ€ ๊ฐ€์ง„ ๊ฐ’์€ 8-bit๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์—†๋‹ค. ๋”ฐ๋ผ์„œ 16bit์˜ ๊ฒฝ์šฐ์—๋Š” ๋ ˆ์ง€์Šคํ„ฐ๋ฅผ ๋‘˜๋กœ ๋‚˜๋ˆ„์–ด ๋ฐ์ดํ„ฐ์˜ low๋ถ€๋ถ„๊ณผ high๋ถ€๋ถ„์„ unsigned๊ฐ’์œผ๋กœ ์ฝ์–ด๋‚ด ๋‘ ๋ฐ”์ดํŠธ๋ฅผ ํ•ฉ์ณ doubleํ˜•์œผ๋กœ ์ €์žฅํ•œ๋‹ค. ์‹ค์ œ ๊ฐ’์€ 2's complement์ด๋ฏ€๋กœ ๋ถ€ํ˜ธ๊ฐ€ ์ค‘ํ•˜๊ธฐ์— unsiigned๋กœ ๋ฐ›์•„ ํ•ฉ์น˜๋Š” ๊ฒƒ์ด๋‹ค.

 

์ฝ”๋“œ ์ „๋ฌธ์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

 

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>
#include <sys/ioctl.h>

static const char* I2C_DEV = "/dev/i2c-1"; 	
static const int I2C_SLAVE = 0x0703; 		

static const int HTS221_ID = 0x5F; 		

static const int CTRL1 = 0x20; 		
static const int CTRL2 = 0x21;

static const int humi_x_0l = 0x36;
static const int humi_x_0h = 0x37;
static const int humi_x_1l = 0x3A;
static const int humi_x_1h = 0x3B;

static const int humi_y_0 = 0x30;
static const int humi_y_1 = 0x31;

static const int temp_x_0l = 0x3C;
static const int temp_x_0h = 0x3D;
static const int temp_x_1l = 0x3E;
static const int temp_x_1h = 0x3F;

static const int temp_y_0l = 0x32;
static const int temp_y_1l = 0x33;

static const int temp_y_01h = 0x35;

static const int temp_out_l = 0x2A;
static const int temp_out_h = 0x2B;
static const int humi_out_l = 0x28;
static const int humi_out_h = 0x29;

void getdata(int fd, double *temperature, double *humidity);

int main() {

    int i2c_fd;
    double temperature, humidity;       //2 bytes

    i2c_fd = open(I2C_DEV, O_RDWR);
    
    ioctl(i2c_fd, I2C_SLAVE, HTS221_ID);

    for(int i = 0 ; i < 10 ; i++ ) {
        wiringPiI2CWriteReg8(i2c_fd, CTRL1, 0x00); //powerdown
        wiringPiI2CWriteReg8(i2c_fd, CTRL1, 0x84); //active mode & register update resist
        wiringPiI2CWriteReg8(i2c_fd, CTRL2, 0x01); //oneshot enable

        getdata(i2c_fd, &temperature, &humidity);

        printf("Temp : %.2f C\n", temperature);
        printf("Humi : %.0f%% rH\n", humidity);

        delay(1000);
    }
    wiringPiI2CWriteReg8(i2c_fd, CTRL1, 0x00); //powerdown HTS221    
    close(i2c_fd);

    return 0;
}

void getdata(int fd, double *temperature, double *humidity) {
    int result;

    do {
        delay(100);
        result = wiringPiI2CReadReg8(fd, CTRL2);
    } while (result != 0);  //run untill ctrl_reg goes to zero.

    //humi x & y
    unsigned char HUMI_x_0l = wiringPiI2CReadReg8(fd, humi_x_0l);
    unsigned char HUMI_x_0h = wiringPiI2CReadReg8(fd, humi_x_0h);
    unsigned char HUMI_x_1l = wiringPiI2CReadReg8(fd, humi_x_1l);
    unsigned char HUMI_x_1h = wiringPiI2CReadReg8(fd, humi_x_1h);

    unsigned char HUMI_y_0_raw = wiringPiI2CReadReg8(fd, humi_y_0);
    unsigned char HUMI_y_1_raw = wiringPiI2CReadReg8(fd, humi_y_1);

    //temp x & y
    unsigned char TEMP_x_0l = wiringPiI2CReadReg8(fd, temp_x_0l);
    unsigned char TEMP_x_0h = wiringPiI2CReadReg8(fd, temp_x_0h);
    unsigned char TEMP_x_1l = wiringPiI2CReadReg8(fd, temp_x_1l);
    unsigned char TEMP_x_1h = wiringPiI2CReadReg8(fd, temp_x_1h);

    unsigned char TEMP_y_0l = wiringPiI2CReadReg8(fd, temp_y_0l);
    unsigned char TEMP_y_1l = wiringPiI2CReadReg8(fd, temp_y_1l);
    unsigned char TEMP_y_01h = wiringPiI2CReadReg8(fd, temp_y_01h);
    //use unsinged char. becuase of 2's complement.
    //and A register has only 8-bit.
    //if use just char, 2 byte date short = (2's comp)(2's comp)  is not correct
    //in code, 2byte datas are 2's complement.
    //humi-y, msb-data, temp-y are unsinged type.
    unsigned char TEMP_out_l = wiringPiI2CReadReg8(fd, temp_out_l);
    unsigned char TEMP_out_h = wiringPiI2CReadReg8(fd, temp_out_h);
    unsigned char HUMI_out_l = wiringPiI2CReadReg8(fd, humi_out_l);
    unsigned char HUMI_out_h = wiringPiI2CReadReg8(fd, humi_out_h);

    //bit setting - cartesian-X
    short HUMI_x_0 = HUMI_x_0h << 8 | HUMI_x_0l;
    short HUMI_x_1 = HUMI_x_1h << 8 | HUMI_x_1l;
    short TEMP_x_0 = TEMP_x_0h << 8 | TEMP_x_0l;
    short TEMP_x_1 = TEMP_x_1h << 8 | TEMP_x_1l;

    //bit setting - cartesian-Y
    double HUMI_y_0 = HUMI_y_0_raw / 2.0;
    double HUMI_y_1 = HUMI_y_1_raw / 2.0;
    double TEMP_y_0 = ((TEMP_y_01h & 0b11) << 8 | TEMP_y_0l) / 8.0;
    double TEMP_y_1 = (((TEMP_y_01h & 0b1100) >> 2 ) << 8 | TEMP_y_1l) / 8.0;

    //bit setting output data
    short TEMP_out = TEMP_out_h << 8 | TEMP_out_l;
    short HUMI_out = HUMI_out_h << 8 | HUMI_out_l;

    //gradient & central data by cartesian
    double gradient_temp = (TEMP_y_1 - TEMP_y_0) / (TEMP_x_1 - TEMP_x_0);
    double gradient_humi = (HUMI_y_1 - HUMI_y_0) / (HUMI_x_1 - HUMI_x_0);

    *temperature = gradient_temp * (TEMP_out - TEMP_x_1) + TEMP_y_1;
    *humidity = gradient_humi * (HUMI_out - HUMI_x_1) + HUMI_y_1;
}

 

gradient๋กœ ๊ธฐ์šธ๊ธฐ๋ฅผ ์ฝ๊ณ , ํ•œ ์ ์„ ์ง€๋‚˜๊ณ  ๊ธฐ์šธ๊ธฐ๋ฅผ ์•„๋Š” ์ง์„ ์˜ ๋ฐฉ์ •์‹์„ ์ด์šฉํ•ด ํ˜„์žฌ ๊ฐ’์„ ์ฝ์–ด๋‚ธ๋‹ค.

'SW > Jetson nano & Raspberry Pi' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

Jetson Nano ์„ธํŒ…ํ•˜๊ธฐ  (0) 2023.07.21
๋ผ์ฆˆ๋ฒ ๋ฆฌํŒŒ์ด4 model B (Raspberrypi4 model B)  (0) 2023.01.22