Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
S
System Programming
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
서현 박
System Programming
Commits
723eadad
Commit
723eadad
authored
1 year ago
by
서현 박
Browse files
Options
Downloads
Patches
Plain Diff
hj
parent
6a3f957f
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
tah.c
+212
-0
212 additions, 0 deletions
tah.c
with
212 additions
and
0 deletions
tah.c
0 → 100644
+
212
−
0
View file @
723eadad
#include
<wiringPi.h>
// wiringPi 라이브러리 사용
#include
<stdio.h>
// 표준입출력용 라이브러리
#include
<stdlib.h>
// 표준 유틸리티용 라이브러리
#include
<stdint.h>
// 정수 자료형 라이브러리
#include
<fcntl.h>
#include
<sys/stat.h>
#include
<sys/types.h>
#include
<unistd.h>
#include
<string.h>
#include
<unistd.h>
#include
<arpa/inet.h>
#include
<pthread.h>
#define MAX_TIMINGS 85 // 최대 신호 추출 개수
#define DHT_PIN 4 // GPIO로 사용할 핀 번호
#define IN 0
#define OUT 1
#define LOWS 0
#define HIGH 1
#define POUT 17
#define VALUE_MAX 40
#define DIRECTION_MAX 128
#define MAX_BUFFER_SIZE 256
// 입력 및 출력을 처리하는 두 개의 스레드 생성
char
buffer
[
MAX_BUFFER_SIZE
];
char
end
[
2
]
=
""
;
int
limit_temperature
=
25
;
// 최고 온도
int
limit_humidity
=
40
;
// 최고 습도
int
data
[
5
]
=
{
0
,
0
,
0
,
0
,
0
};
// 온습도 및 checksum 데이터 저장용 변수 배열
// 에러 메시지 출력 및 프로그램 종료 함수
void
error_handling
(
char
*
message
)
{
fputs
(
message
,
stderr
);
fputc
(
'\n'
,
stderr
);
exit
(
1
);
}
static
int
GPIOWrite
(
int
pin
,
int
value
)
{
static
const
char
s_values_str
[]
=
"01"
;
char
path
[
VALUE_MAX
];
int
fd
;
snprintf
(
path
,
VALUE_MAX
,
"/sys/class/gpio/gpio%d/value"
,
pin
);
fd
=
open
(
path
,
O_WRONLY
);
if
(
-
1
==
fd
)
{
// fprintf(stderr, "Failed to open gpio value for writing!\n");
return
(
-
1
);
}
if
(
1
!=
write
(
fd
,
&
s_values_str
[
LOWS
==
value
?
0
:
1
],
1
))
{
fprintf
(
stderr
,
"Failed to write value!
\n
"
);
return
(
-
1
);
}
close
(
fd
);
return
(
0
);
}
void
LED_GPIO
(){
int
repeat
=
2
;
do
{
GPIOWrite
(
POUT
,
repeat
);
usleep
(
1000
*
1000
);
}
while
(
repeat
--
);
}
void
read_dht_data
()
{
// dht데이터 읽기 함수
uint8_t
laststate
=
HIGH
;
// DHT핀의 상태 저장용 변수(현재 신호가 HIGH인지 LOW인지 확인하기 위한 용도)
uint8_t
counter
=
0
;
// 신호의 길이를 측정하기 위한 카운터 변수
uint8_t
j
=
0
,
i
;
// 40개의 신호 인덱스 용 변수
data
[
0
]
=
data
[
1
]
=
data
[
2
]
=
data
[
3
]
=
data
[
4
]
=
0
;
//초기 데이터 값은 0으로 지정
/* DHT11센서와의 통신을 개시하기 위해 DATA핀을 18ms동안 LOW로 출력 */
pinMode
(
DHT_PIN
,
OUTPUT
);
digitalWrite
(
DHT_PIN
,
0
);
delay
(
18
);
digitalWrite
(
DHT_PIN
,
1
);
delayMicroseconds
(
40
);
pinMode
(
DHT_PIN
,
INPUT
);
/* 핀을 입력모드로 설정해서 DHT11로 부터 응답을 기다림 */
pinMode
(
DHT_PIN
,
INPUT
);
/* DHT11에서 오는 신호 검출 및 데이터비트 추출 */
for
(
i
=
0
;
i
<
MAX_TIMINGS
;
i
++
)
// 총 85번 동안 신호를 확인
{
counter
=
0
;
// 초기 카운터는 0
while
(
digitalRead
(
DHT_PIN
)
==
laststate
)
{
//DHT핀의 신호를 읽어서 현재 지정한 DATA핀 신호와 같은 동안==즉 신호의 변환이 없는 동안
counter
++
;
delayMicroseconds
(
1
);
if
(
counter
==
255
)
// 즉 너무 오래 동안 대기하면==오류가 생겼다는 의미 임
{
break
;
}
}
laststate
=
digitalRead
(
DHT_PIN
);
// 현재 핀 상태 저장
if
(
counter
==
255
)
// 카운터가 255이상 도달했다면, 데이터비트 수신 중지== for문 밖으로 나가서 처음부터 새로 받겠다는 의미임
break
;
/* 첫번째 3개의 신호는 무시하고 짝수번째에 해당하는 신호길이를 읽어 0인지 1인지에 따라 온습도 변수에 저장
첫번째 3개의 신호는 DHT11의 응답 용 신호로 실제 데이터 길이를 통해 정보를 수신하는 값이 아니므로 무시함.
짝수만 추출하는 이유는 짝수 번째의 신호 길이에 따라 해당 신호가 0을 의미하는지 1을 의미하는지를 나타냄.
*/
if
((
i
>=
4
)
&&
(
i
%
2
==
0
))
{
/* 가각의 데이터 비트를 온도 및 습도 변수에 하나씩 넣어줌 */
data
[
j
/
8
]
<<=
1
;
// 이진수의 자리수를 하나씩 옆으로 이동시킴
if
(
counter
>
16
)
// 카운터의 값이 16보다 크다면, 즉 신호의 길이가 길어서 비트 1로 인식된다면
data
[
j
/
8
]
|=
1
;
// 해당 비트는 1을 넣어줌
j
++
;
// 다음 데이터를 위해 인덱스 값을 하나 증가 시킴
}
}
/*
* 40비트를 다 확인했다면 (8비트 x 5 ) 체크섬 데이터와 오류체크를 해서
* 오류가 없으면 데이터를 출력함.
*/
if
((
j
>=
40
)
&&
(
data
[
4
]
==
((
data
[
0
]
+
data
[
1
]
+
data
[
2
]
+
data
[
3
])
&
0xFF
)))
{
//에러가 없으면 습도 및 온도 출력
printf
(
"Humidity = %d.%d %% Temperature = %d.%d C
\n
"
,
data
[
0
],
data
[
1
],
data
[
2
],
data
[
3
]);
if
(
data
[
2
]
>=
limit_temperature
){
//최고 온도 및 최고 습도를 넘을 경우, 온습도기 실행
printf
(
"temperature over
\n
"
);
LED_GPIO
();
}
if
(
data
[
0
]
>=
limit_humidity
){
printf
(
"humidity over
\n
"
);
LED_GPIO
();
}
}
else
{
printf
(
"Data not good, skip
\n
"
);
//에러 발생시 Data not good 메시지 출력
}
}
void
*
thread_socket_to_output
()
{
while
(
1
){
read_dht_data
();
// 온도 및 습도 데이터 획득 및 출력
delay
(
1000
);
// 다음 읽기까지 2초 대기
if
(
strcmp
(
end
,
"e"
)
==
0
)
{
LED_GPIO
();
break
;
}
}
}
void
*
read_func
(
void
*
arg
)
{
int
client_socket
=
*
(
int
*
)
arg
;
while
(
1
){
int
str_len
=
read
(
client_socket
,
buffer
,
sizeof
(
buffer
));
if
(
strcmp
(
buffer
,
"e"
)
==
0
){
strcpy
(
end
,
"e"
);
break
;
}
}
}
int
main
(
int
argc
,
char
*
argv
[])
{
int
client_socket
;
struct
sockaddr_in
server_address
;
int
thr_id
;
int
status
;
pthread_t
p_thread
[
2
];
printf
(
"Raspberry Pi DHT11 temperature/humidity test
\n
"
);
if
(
wiringPiSetupGpio
()
==
-
1
)
//라즈베리파이의 BCM GPIO 핀번호를 사용하겠다고 선언
exit
(
1
);
// 클라이언트 소켓 생성
client_socket
=
socket
(
PF_INET
,
SOCK_STREAM
,
0
);
if
(
client_socket
==
-
1
)
error_handling
(
"socket() error"
);
// 서버 주소 설정
memset
(
&
server_address
,
0
,
sizeof
(
server_address
));
server_address
.
sin_family
=
AF_INET
;
server_address
.
sin_addr
.
s_addr
=
inet_addr
(
argv
[
1
]);
server_address
.
sin_port
=
htons
(
atoi
(
argv
[
2
]));
// 서버에 연결
if
(
connect
(
client_socket
,
(
struct
sockaddr
*
)
&
server_address
,
sizeof
(
server_address
))
==
-
1
)
error_handling
(
"connect() error"
);
printf
(
"Connected to server
\n
"
);
while
(
1
){
int
str_len
=
read
(
client_socket
,
buffer
,
sizeof
(
buffer
));
if
(
strcmp
(
buffer
,
"s"
)
==
0
){
thr_id
=
pthread_create
(
&
p_thread
[
0
],
NULL
,
read_func
,
&
client_socket
);
if
(
thr_id
<
0
)
error_handling
(
"thread create error : "
);
thr_id
=
pthread_create
(
&
p_thread
[
1
],
NULL
,
thread_socket_to_output
,
NULL
);
if
(
thr_id
<
0
)
error_handling
(
"thread create error : "
);
// 스레드가 종료될 때까지 대기
pthread_join
(
p_thread
[
0
],
(
void
**
)
&
status
);
pthread_join
(
p_thread
[
1
],
(
void
**
)
&
status
);
break
;
}
}
return
(
0
);
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment