๐ ๊ณต๋ถํ๋ ์ง์ง์ํ์นด๋ ์ฒ์์ด์ง?
[๋ฆฌ๋ ์ค ์์คํ ํ๋ก๊ทธ๋๋ฐ๊ณผ ๋ผ์ฆ๋ฒ ๋ฆฌ ํ์ด์ ์ ์ด] SenseHAT ๋ณธ๋ฌธ
[๋ฆฌ๋ ์ค ์์คํ ํ๋ก๊ทธ๋๋ฐ๊ณผ ๋ผ์ฆ๋ฒ ๋ฆฌ ํ์ด์ ์ ์ด] SenseHAT
์ง์ง์ํ์นด 2024. 1. 8. 19:49<์์์ง ๋์ ์ฌ๋ฌผ์ธํฐ๋ท์ ์ํ ๋ฆฌ๋ ์ค ํ๋ก๊ทธ๋๋ฐ with ๋ผ์ฆ๋ฒ ๋ฆฌํ์ด ์์ ์ ์ฐธ๊ณ ํด์ ์์ฑํ์์ต๋๋ค :-)>
โญ WiringPi
๋ผ์ฆ๋ฒ ๋ฆฌํ์ด์ GPIO ํ ์ ์ด๋ฅผ ์ํ C์ธ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ธ WiringPi ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ค์น
// ๊ธฐ์กด์ ๋ค๋ฅธ ํจํค์ง๊ฐ ์ฐธ์กฐ ํ๋ค๊ณ ์๋ฌ ๋จ. ๊ทธ๋์ ์ญ์ ํจ
sudo apt purge wiringpi
hash -r
git clone https://github.com/WiringPi/WiringPi.git
cd WiringPi
git pull origin
./build
gpio -v
โญ ๋ผ์ฆ๋ฒ ๋ฆฌ ํ์ด์ SenseHAT ์ ์ดํ๋ ์ ํ๋ฆฌ์ผ์ด์
๋ผ์ฆ๋ฒ ๋ฆฌ ํ์ด์ SenseHAT ์ ์ ์ดํ๋ ์ ํ๋ฆฌ์ผ์ด์
SenseHAT ์ ๊ธฐ์ ๊ด์ธก ์์คํ
์ ๋ง๋ค ์ ์๋ ๊ธฐ์ ์ผ์, ์จ์ต๋ ์ผ์ ํ์ฌํจ
๊ธฐ์ ์ผ์(LPS25H), ์จ์ต๋ ์ผ์(HTS221)
2๊ฐ์ ์ผ์์ ๋ํ ํ์ผ ๋์คํฌ๋ฆฝํฐ ๊ฐ๊ฐ ์์ฑ + ์ด๊ธฐํ
p ๋ฅผ ๋๋ฌ์ LPS25H ์ผ์์ ๊ธฐ์๊ณผ ์จ๋ ์ถ๋ ฅ
t ๋ฅผ ๋๋ฌ์ HTS221 ์ผ์์ ์จ๋์ ์ต๋ ์ถ๋ ฅ
kbhit() ํจ์ ์ด์ฉํด์ ํ์ฌ ํค๋ณด๋์์ ๋๋ฅธ ๋ฌธ์์ด ๊ฐ์ ธ์ค๊ณ , ๊ฐ ์ผ์๋ฅผ ์ ์ดํจ
ํ๋์ ํ๋ก์ธ์ค๋ง ์ฌ์ฉํ๊ณ ์์ด์ ๋ค๋ฅธ ๋์ ์ํ X
// ๋ผ์ฆ๋ฒ ๋ฆฌ ํ์ด์ SenseHAT ์ ์ ์ดํ๋ ์ ํ๋ฆฌ์ผ์ด์
// SenseHAT ์ ๊ธฐ์ ๊ด์ธก ์์คํ
์ ๋ง๋ค ์ ์๋ ๊ธฐ์ ์ผ์, ์จ์ต๋ ์ผ์ ํ์ฌํจ
// ๊ธฐ์ ์ผ์(LPS25H), ์จ์ต๋ ์ผ์(HTS221)
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>
#include <sys/ioctl.h>
// I2C๋ฅผ ์ํ ์ฅ์น ํ์ผ
static const char* I2C_DEV = "/dev/i2c-1";
// ioctl() ํจ์์์ I2C_SLAVE ์ค์ ์ ์ํ ๊ฐ
static const int I2C_SLAVE = 0x0703;
// SenseHAT ์ i2c-1 ๊ฐ
static const int LPS25H_ID = 0x5C;
static const int HTS221_ID = 0x5F;
// STMicroelectronics ์ ์คํ ๋ฌธ์ ๊ฐ
static const int CTRL_REG1 = 0x20;
static const int CTRL_REG2 = 0x21;
// STMicroelectronics ์ LPS25H ์คํ ๋ฌธ์ ๊ฐ
static const int PRESS_OUT_XL = 0x28;
static const int PRESS_OUT_L = 0x29;
static const int PRESS_OUT_H = 0x2A;
static const int PTEMP_OUT_L = 0x2B;
static const int PTEMP_OUT_H = 0x2C;
// STMicroelectronics ์ HTS221 ์คํ ๋ฌธ์ ๊ฐ
static const int H0_T0_OUT_L = 0x36;
static const int H0_T0_OUT_H = 0x37;
static const int H1_T0_OUT_L = 0x3A;
static const int H1_T0_OUT_H = 0x3B;
static const int H0_rH_x2 = 0x30;
static const int H1_rH_x2 = 0x31;
static const int H_T_OUT_L = 0x28;
static const int H_T_OUT_H = 0x29;
static const int T0_OUT_L = 0x3C;
static const int T0_OUT_H = 0x3D;
static const int T1_OUT_L = 0x3E;
static const int T1_OUT_H = 0x3F;
static const int T0_degC_x8 = 0x32;
static const int T1_degC_x8 = 0x33;
static const int T1_T0_MSB = 0x35;
static const int TEMP_OUT_L = 0x2A;
static const int TEMP_OUT_H = 0x2B;
int kbhit(void);
// ๊ธฐ์๊ณผ ์จ๋๋ฅผ ์ํ ํจ์
void getPressure(int fd, double *temperature, double *pressure);
// ์จ๋์ ์ต๋๋ฅผ ์ํ ํจ์
void getTemperature(int fd, double *temperature, double *humidity);
int main(int argc, char **argv) {
int i = 0;
int pressure_fd, temperature_fd;
// ์จ๋์ ์๋ ฅ, ์ต๋๋ฅผ ์ถ๋ ฅํ๊ธฐ ์ํ ๋ณ์
double t_c = 0.0;
double temperature, humidity;
// => 2๊ฐ์ ์ผ์์ ๋ํ ํ์ผ ๋์คํฌ๋ฆฝํฐ ๊ฐ๊ฐ ์์ฑ + ์ด๊ธฐํ
// => p ๋ฅผ ๋๋ฌ์ LPS25H ์ผ์์ ๊ธฐ์๊ณผ ์จ๋ ์ถ๋ ฅ
// => t ๋ฅผ ๋๋ฌ์ HTS221 ์ผ์์ ์จ๋์ ์ต๋ ์ถ๋ ฅ
// => kbhit() ํจ์ ์ด์ฉํด์ ํ์ฌ ํค๋ณด๋์์ ๋๋ฅธ ๋ฌธ์์ด ๊ฐ์ ธ์ค๊ณ , ๊ฐ ์ผ์๋ฅผ ์ ์ดํจ
// => ํ๋์ ํ๋ก์ธ์ค๋ง ์ฌ์ฉํ๊ณ ์์ด์ ๋ค๋ฅธ ๋์ ์ํ X
// I2C ์ฅ์น ํ์ผ ์คํ
if ((pressure_fd = open(I2C_DEV, O_RDWR)) < 0) {
perror("Unable to open i2c device");
return 1;
}
// I2C ์ฅ์น๋ฅผ ์ฌ๋ ์ดํ ๋ชจ๋๋ก LPS25H ์ค์
if (ioctl(pressure_fd, I2C_SLAVE, LPS25H_ID) < 0) {
perror("Unable to configure i2c slave device");
close(pressure_fd);
return 1;
}
// I2C ์ฅ์น ํ์ผ ์คํ
if ((temperature_fd = open(I2C_DEV, O_RDWR)) < 0) {
perror("Unable to open i2c device");
return 1;
}
// I2C ์ฅ์น๋ฅผ ์ฌ๋ ์ด๋ธ ๋ชจ๋๋ก HTS221 ์ค์
if (ioctl(temperature_fd, I2C_SLAVE, HTS221_ID) < 0) {
perror("Unable to configure i2c slave device");
return 1;
}
printf("p : Pressure, t : Temperature, q : Quit\n");
for (i = 0; ; i++) {
// ํค๋ณด๋๊ฐ ๋๋ ธ๋์ง ํ์ธ
if (kbhit()) {
// ๋ฌธ์ ์ฝ๋๋ค
switch(getchar()) {
case "p":
// LPS25H ์ฅ์น ์ด๊ธฐํ
wiringPiI2CWriteReg8(pressure_fd, CTRL_REG1, 0x00);
wiringPiI2CWriteReg8(pressure_fd, CTRL_REG1, 0x84);
wiringPiI2CWriteReg8(pressure_fd, CTRL_REG2, 0x01);
// ๊ธฐ์๊ณผ ์จ๋ ๊ฐ ์ป๊ธฐ
getPressure(pressure_fd, &t_c, &pressure);
// ๊ณ์ฐ๋ ๊ฐ ์ถ๋ ฅ
printf("Temperature(from LPS25H) = %.2f C\n", t_c);
printf("Pressure = %.0f hpa\n", pressure);
break;
case "t":
// HTS221 ์ฅ์น ์ด๊ธฐํ
wiringPiI2CWriteReg8(temperature_fd, CTRL_REG1, 0x00);
wiringPiI2CWriteReg8(temperature_fd, CTRL_REG1, 0x84);
wiringPiI2CWriteReg8(temperature_fd, CTRL_REG2, 0x01);
// ์จ๋์ ์ต๋ ๊ฐ ์ป๊ธฐ
getPressure(temperature_fd, &temperature, &humidity);
// ๊ณ์ฐ๋ ๊ฐ ์ถ๋ ฅ
printf("Temperature(from LPS25H) = %.2f C\n", temperature);
printf("Humidity = %.0f%% rH\n", humidity);
break;
case "q":
goto END;
break;
};
}
printf("%20d\t\t\r", i);
delay(100);
}
END:
printf("Good Bye!\n");
// ์ฌ์ฉ ๋๋ ์ฅ์น ์ ๋ฆฌ
wiringPiI2CWriteReg8(pressure_fd, CTRL_REG1, 0x00);
close(pressure_fd);
wiringPiI2CWriteReg8(temperature_fd, CTRL_REG1, 0x00);
close(temperature_fd);
return 0;
}
// ํค๋ณด๋ ์
๋ ฅ ์ฒ๋ฆฌ ํจ์
int kbhit(void) {
// ํฐ๋ฏธ๋์ ๋ํ ๊ตฌ์กฐ์ฒด
struct termios oldt, newt;
int ch, oldf;
// ํ์ฌ ํฐ๋ฏธ๋์ ์ค์ ๋ ์ ๋ณด ๊ฐ์ ธ์ด
tcgetattr(0, &oldt);
newt = oldt;
// ์ ๊ท ๋ชจ๋ ์
๋ ฅ๊ณผ ์์ฝ๋ฅผ ํด์ (ICANON ์ ๊ท๋ชจ๋๋ก ์
๋ ฅ์ด ์ด๋ค์ง๊ฒ ํจ, ECHO ๋ ํค๋ณด๋๋ก ์
๋ ฅํ ๋ด์ฉ์ ๋ชจ๋ํฐ๋ก ์ถ๋ ฅํ๋๋ก ํจ)
newt.c_lflag &= ~(ICANON | ECHO);
// ์๋ก์ด ๊ฐ์ผ๋ก ํฐ๋ฏธ๋ ์ค์ (TCSANOW ๋ฐ๋ก ํฐ๋ฏธ๋์ ๋ณ๊ฒฝ๋ ์์ฑ์ด ์ ์ฉ๋๋๋ก ํจ)
tcsetattr(0, TCSANOW, &newt);
oldf = fcntl(0, F_GETFL, 0);
// ์
๋ ฅ์ ๋
ผ๋ธ๋กํน ๋ชจ๋๋ก ์ค์
fcntl(0, F_SETFL, oldf | O_NONBLOCK);
// getchar() : ํค๋ณด๋๋ก ์
๋ ฅ๋ ๋ฌธ์๊ฐ ํ๋ฉด์ ์๋์ผ๋ก ์ถ๋ ฅ๋จ
ch = getchar();
if (ch != EOF) {
// ์์์ ์ฝ์ผ๋ฉฐ ๊บผ๋ธ ๋ฌธ์๋ฅผ ๋ค์ ๋ฃ๋๋ค
ungetc(ch, stdin);
}
return 0;
}
// ๊ธฐ์๊ณผ ์จ๋ ๊ณ์ฐ ํจ์
void getPressure(int fd, double *temperature, double *pressure)
{
int result;
unsigned char temp_out_l = 0, temp_out_h = 0; /* ์จ๋๋ฅผ ๊ณ์ฐํ๊ธฐ ์ํ ๋ณ์ */
unsigned char press_out_xl = 0; /* ๊ธฐ์์ ๊ณ์ฐํ๊ธฐ ์ํ ๋ณ์ */
unsigned char press_out_l = 0;
unsigned char press_out_h = 0;
short temp_out = 0; /* ์จ๋์ ์๋ ฅ์ ์ ์ฅํ๊ธฐ ์ํ ๋ณ์ */
int press_out = 0;
/* ์ธก์ ์ด ์๋ฃ๋ ๋๊น์ง ๋๊ธฐ */
do {
delay(25); /* 25๋ฐ๋ฆฌ์ด ๋๊ธฐ */
result = wiringPiI2CReadReg8(fd, CTRL_REG2);
} while(result != 0);
/* ์ธก์ ๋ ์จ๋ ๊ฐ ์ฝ๊ธฐ(2๋ฐ์ดํธ ์ฝ๊ธฐ) */
temp_out_l = wiringPiI2CReadReg8(fd, PTEMP_OUT_L);
temp_out_h = wiringPiI2CReadReg8(fd, PTEMP_OUT_H);
/* ์ธก์ ๋ ๊ธฐ์ ๊ฐ ์ฝ๊ธฐ(3๋ฐ์ดํธ ์ฝ๊ธฐ) */
press_out_xl = wiringPiI2CReadReg8(fd, PRESS_OUT_XL);
press_out_l = wiringPiI2CReadReg8(fd, PRESS_OUT_L);
press_out_h = wiringPiI2CReadReg8(fd, PRESS_OUT_H);
/* ๊ฐ๊ฐ ์ธก์ ํ ๊ฐ๋ค์ ํฉ์ฑํด์ ์จ๋(16๋นํธ)์ ๊ธฐ์(24๋นํธ) ๊ฐ ์์ฑ(๋นํธ/์ํํธ ์ด์ฉ) */
temp_out = temp_out_h << 8 | temp_out_l;
press_out = press_out_h << 16 | press_out_l << 8 | press_out_xl;
/* ์ถ๋ ฅ๊ฐ ๊ณ์ฐ */
*temperature = 42.5 + (temp_out / 480.0);
*pressure = press_out / 4096.0;
}
// ์จ๋์ ์ต๋๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํ ํจ์
void getTemperature(int fd, double *temperature, double *humidity)
{
int result;
/* ์ธก์ ์ด ์๋ฃ๋ ๋๊น์ง ๋๊ธฐ */
do {
delay(25); /* 25๋ฐ๋ฆฌ์ด ๋๊ธฐ */
result = wiringPiI2CReadReg8(fd, CTRL_REG2);
} while(result != 0);
/* ์จ๋(LSB(ADC))๋ฅผ ์ํ ๋ณด์ ๊ฐ(x-๋ฐ์ดํฐ๋ฅผ ์ํ 2์ง์ ) ์ฝ๊ธฐ */
unsigned char t0_out_l = wiringPiI2CReadReg8(fd, T0_OUT_L);
unsigned char t0_out_h = wiringPiI2CReadReg8(fd, T0_OUT_H);
unsigned char t1_out_l = wiringPiI2CReadReg8(fd, T1_OUT_L);
unsigned char t1_out_h = wiringPiI2CReadReg8(fd, T1_OUT_H);
/* ์จ๋(°C)๋ฅผ ์ํ ๋ณด์ ๊ฐ(y-๋ฐ์ดํฐ๋ฅผ ์ํ 2์ง์ ) ์ฝ๊ธฐ */
unsigned char t0_degC_x8 = wiringPiI2CReadReg8(fd, T0_degC_x8);
unsigned char t1_degC_x8 = wiringPiI2CReadReg8(fd, T1_degC_x8);
unsigned char t1_t0_msb = wiringPiI2CReadReg8(fd, T1_T0_MSB);
/* ์ต๋(LSB(ADC))๋ฅผ ์ํ ๋ณด์ ๊ฐ(x-๋ฐ์ดํฐ๋ฅผ ์ํ 2์ง์ ) ์ฝ๊ธฐ */
unsigned char h0_out_l = wiringPiI2CReadReg8(fd, H0_T0_OUT_L);
unsigned char h0_out_h = wiringPiI2CReadReg8(fd, H0_T0_OUT_H);
unsigned char h1_out_l = wiringPiI2CReadReg8(fd, H1_T0_OUT_L);
unsigned char h1_out_h = wiringPiI2CReadReg8(fd, H1_T0_OUT_H);
/*์ต๋(% rH)๋ฅผ ์ํ ๋ณด์ ๊ฐ(y-๋ฐ์ดํฐ๋ฅผ ์ํ 2์ง์ ) ์ฝ๊ธฐ */
unsigned char h0_rh_x2 = wiringPiI2CReadReg8(fd, H0_rH_x2);
unsigned char h1_rh_x2 = wiringPiI2CReadReg8(fd, H1_rH_x2);
/* ๊ฐ๊ฐ ์ธก์ ํ ๊ฐ๋ค์ ํฉ์ฑํด์ ์จ๋(x-๊ฐ) ๊ฐ ์์ฑ(๋นํธ/์ํํธ ์ด์ฉ) */
short s_t0_out = t0_out_h << 8 | t0_out_l;
short s_t1_out = t1_out_h << 8 | t1_out_l;
/* ๊ฐ๊ฐ ์ธก์ ํ ๊ฐ๋ค์ ํฉ์ฑํด์ ์ต๋(x-๊ฐ) ๊ฐ ์์ฑ(๋นํธ/์ํํธ ์ด์ฉ) */
short s_h0_t0_out = h0_out_h << 8 | h0_out_l;
short s_h1_t0_out = h1_out_h << 8 | h1_out_l;
/* 16๋นํธ์ 10๋นํธ์ ๊ฐ ์์ฑ(๋นํธ ๋ง์คํฌ/์ํํธ ์ด์ฉ) */
unsigned short s_t0_degC_x8 = (t1_t0_msb & 3) << 8 | t0_degC_x8;
unsigned short s_t1_degC_x8 = ((t1_t0_msb & 12) >> 2) << 8 | t1_degC_x8;
/* ์จ๋ ๋ณด์ ๊ฐ(y-๊ฐ) ๊ณ์ฐ */
double d_t0_degC = s_t0_degC_x8 / 8.0;
double d_t1_degC = s_t1_degC_x8 / 8.0;
/* ์ต๋ ๋ณด์ ๊ฐ(y-๊ฐ) ๊ณ์ฐ */
double h0_rH = h0_rh_x2 / 2.0;
double h1_rH = h1_rh_x2 / 2.0;
/* ์จ๋์ ์ต๋์ ๊ณ์ฐ์ ์ํ ๋ณด์ ์ ํ ์ง์ ๊ทธ๋ํ 'y = mx + c' ๊ณต์์ ๊ณ์ฐ */
double t_gradient_m = (d_t1_degC - d_t0_degC) / (s_t1_out - s_t0_out);
double t_intercept_c = d_t1_degC - (t_gradient_m * s_t1_out);
double h_gradient_m = (h1_rH - h0_rH) / (s_h1_t0_out - s_h0_t0_out);
double h_intercept_c = h1_rH - (h_gradient_m * s_h1_t0_out);
/* ์ฃผ๋ณ์ ์จ๋ ์ฝ๊ธฐ(2๋ฐ์ดํธ ์ฝ๊ธฐ) */
unsigned char t_out_l = wiringPiI2CReadReg8(fd, TEMP_OUT_L);
unsigned char t_out_h = wiringPiI2CReadReg8(fd, TEMP_OUT_H);
/* 16๋นํธ ๊ฐ ์์ฑ */
short s_t_out = t_out_h << 8 | t_out_l;
/* ์ฃผ๋ณ์ ์ต๋ ์ฝ๊ธฐ(2๋ฐ์ดํธ ์ฝ๊ธฐ) */
unsigned char h_t_out_l = wiringPiI2CReadReg8(fd, H_T_OUT_L);
unsigned char h_t_out_h = wiringPiI2CReadReg8(fd, H_T_OUT_H);
/* 16๋นํธ ๊ฐ ์์ฑ */
short s_h_t_out = h_t_out_h << 8 | h_t_out_l;
/* ์ฃผ๋ณ์ ์จ๋ ๊ณ์ฐ */
*temperature = (t_gradient_m * s_t_out) + t_intercept_c;
/* ์ฃผ๋ณ์ ์ต๋ ๊ณ์ฐ */
*humidity = (h_gradient_m * s_h_t_out) + h_intercept_c;
}
BUT.. ์ฐ๋๋ SenseHAT ์ด ์๋ค!
'๐ฉโ๐ป IoT (Embedded) > Raspberry Pi' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[ํ๋ก์ธ์ค์ ์๊ทธ๋] ํ๋ก์ธ์ค (Process) (0) | 2024.01.08 |
---|---|
๋ฆฌ๋ ์ค ํ๋ก๊ทธ๋๋ฐ์ ๊ธฐ์ด (1) | 2024.01.08 |
[๋๋ ํฐ๋ฆฌ์ ์๊ฐ ์ฒ๋ฆฌ] ํ์ฌ์ ์๊ฐ์ ์ถ๋ ฅํ๊ธฐ (1) | 2024.01.08 |
[๋๋ ํฐ๋ฆฌ์ ์๊ฐ ์ฒ๋ฆฌ] ๋๋ ํฐ๋ฆฌ์ ๋ํ ์ ๋ณด ์ถ๋ ฅํ๊ธฐ ( = $ ls -RI) (1) | 2024.01.07 |
[ํ์ผ ์ ๋ณด์ ๊ถํ] ํ์ผ์ ์ ๊ทผ ๊ถํ ๋ฐ ๋ณ๊ฒฝ with ๋งํฌ (1) | 2024.01.06 |