Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
S
systemprogramming-4
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
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
GitLab community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Eunchae Lee
systemprogramming-4
Commits
e2aac1cf
Commit
e2aac1cf
authored
1 year ago
by
Eunchae Lee
Browse files
Options
Downloads
Patches
Plain Diff
Delete 0607server.c
parent
625a9880
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
0607server.c
+0
-520
0 additions, 520 deletions
0607server.c
with
0 additions
and
520 deletions
0607server.c
deleted
100644 → 0
+
0
−
520
View file @
625a9880
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>
#include
<unistd.h>
#include
<pthread.h>
#include
<arpa/inet.h>
#include
<fcntl.h>
#include
<math.h>
// GPIO 및 PWM 관련 설정
#define POUT 18 // GPIO 18번 핀 (PWM0)
#define PWM_PIN 0 // PWM0
#define SERVER_PORT 8080
#define BUFFER_SIZE 1024
#define VALUE_MAX 40
#define DIRECTION_MAX 35
#define LOW 0
#define HIGH 1
#define IN 0
#define BUFFER_MAX 3
// 특정 클라이언트 IP 주소
#define TEMP_CLIENT_IP "192.168.45.11"
#define LIGHT_CLIENT_IP "192.168.45.10"
// WBGT 임계치
#define WBGT_THRESHOLD 20.0
// 데이터 저장용 전역 변수
float
temperature
=
0
.
0
,
humidity
=
0
.
0
,
tg
=
0
.
0
,
wbgt
=
0
.
0
,
hum_temperature
=
0
.
0
;
int
temp_data_received
=
0
,
light_data_received
=
0
;
// 수신 상태 플래그
// GPIO 및 PWM 필요한 함수들 선언
static
int
PWMEnable
(
int
pwmnum
);
static
int
GPIOExport
(
int
pin
);
static
int
GPIODirection
(
int
pin
,
int
dir
);
static
int
GPIOWrite
(
int
pin
,
int
value
);
static
int
GPIOUnexport
(
int
pin
);
static
int
PWMExport
(
int
pwmnum
);
static
int
PWMWritePeriod
(
int
pwmnum
,
int
value
);
static
int
PWMWriteDutyCycle
(
int
pwmnum
,
int
value
);
void
*
handle_client_temp
(
void
*
arg
);
void
*
handle_client_light
(
void
*
arg
);
void
process_wbgt_and_buzzer
();
void
*
handle_client
(
void
*
arg
)
{
int
client_sock
=
*
(
int
*
)
arg
;
struct
sockaddr_in
client_addr
;
socklen_t
client_addr_len
=
sizeof
(
client_addr
);
getpeername
(
client_sock
,
(
struct
sockaddr
*
)
&
client_addr
,
&
client_addr_len
);
char
client_ip
[
INET_ADDRSTRLEN
];
inet_ntop
(
AF_INET
,
&
client_addr
.
sin_addr
,
client_ip
,
INET_ADDRSTRLEN
);
if
(
strcmp
(
client_ip
,
TEMP_CLIENT_IP
)
==
0
)
{
printf
(
"Temperature client connected: %s
\n
"
,
client_ip
);
handle_client_temp
(
arg
);
}
else
if
(
strcmp
(
client_ip
,
LIGHT_CLIENT_IP
)
==
0
)
{
printf
(
"Light client connected: %s
\n
"
,
client_ip
);
handle_client_light
(
arg
);
}
else
{
printf
(
"Unknown client connected: %s
\n
"
,
client_ip
);
close
(
client_sock
);
free
(
arg
);
}
return
NULL
;
}
void
*
handle_client_temp
(
void
*
arg
)
{
int
client_sock
=
*
(
int
*
)
arg
;
char
buffer
[
BUFFER_SIZE
];
int
bytes_received
;
while
(
1
)
{
bytes_received
=
recv
(
client_sock
,
buffer
,
BUFFER_SIZE
,
0
);
if
(
bytes_received
<=
0
)
{
if
(
bytes_received
==
0
)
{
printf
(
"Temperature client disconnected
\n
"
);
}
else
{
perror
(
"recv failed"
);
}
break
;
}
buffer
[
bytes_received
]
=
'\0'
;
printf
(
"Received temperature data: %s
\n
"
,
buffer
);
// 문자열에서 온도와 습도를 파싱
if
(
sscanf
(
buffer
,
"%f %f"
,
&
temperature
,
&
humidity
)
==
2
)
{
printf
(
"Parsed Temperature: %.1f, Humidity: %.1f
\n
"
,
temperature
,
humidity
);
hum_temperature
=
temperature
*
atan
(
0
.
152
*
sqrt
(
humidity
+
8
.
3136
))
+
atan
(
temperature
+
humidity
)
-
atan
(
humidity
-
1
.
67633
)
+
0
.
003
91838
*
pow
(
humidity
,
1
.
5
)
*
atan
(
0
.
0231
*
humidity
)
-
4
.
686
;
humidity
=
hum_temperature
;
temp_data_received
=
1
;
// 온도 데이터 수신 완료 플래그
// 온습도 데이터를 받은 후 조도 데이터 수신 상태 확인 후 WBGT 처리
process_wbgt_and_buzzer
();
}
else
{
printf
(
"Failed to parse temperature and humidity
\n
"
);
}
}
close
(
client_sock
);
free
(
arg
);
return
NULL
;
}
void
*
handle_client_light
(
void
*
arg
)
{
int
client_sock
=
*
(
int
*
)
arg
;
char
buffer
[
BUFFER_SIZE
];
int
bytes_received
;
while
(
1
)
{
bytes_received
=
recv
(
client_sock
,
buffer
,
BUFFER_SIZE
,
0
);
if
(
bytes_received
<=
0
)
{
if
(
bytes_received
==
0
)
{
printf
(
"Light client disconnected
\n
"
);
}
else
{
perror
(
"recv failed"
);
}
break
;
}
buffer
[
bytes_received
]
=
'\0'
;
printf
(
"Received light data: %s
\n
"
,
buffer
);
// 데이터를 파싱하여 조도 추출
int
light
;
if
(
sscanf
(
buffer
,
"%d"
,
&
light
)
==
1
)
{
printf
(
"Light intensity: %d
\n
"
,
light
);
tg
=
temperature
+
(
0
.
02
*
light
)
/
100
.
0
;
// 흑구온도 계산
light_data_received
=
1
;
// 조도 데이터 수신 완료 플래그
// 조도 데이터를 받은 후 온습도 데이터 수신 상태 확인 후 WBGT 처리
process_wbgt_and_buzzer
();
}
else
{
printf
(
"Failed to parse light data
\n
"
);
}
}
close
(
client_sock
);
free
(
arg
);
return
NULL
;
}
void
process_wbgt_and_buzzer
()
{
if
(
temp_data_received
&&
light_data_received
)
{
// WBGT 계산
printf
(
"Temperature: %.1f, Humidity: %.1f, Tg: %.1f
\n
"
,
temperature
,
humidity
,
tg
);
wbgt
=
0
.
7
*
humidity
+
0
.
2
*
temperature
+
0
.
1
*
tg
;
printf
(
"Calculated WBGT: %.1f
\n
"
,
wbgt
);
// WBGT 값이 임계치를 초과하면 부저를 울림
if
(
wbgt
>=
WBGT_THRESHOLD
)
{
printf
(
"WBGT %.1f exceeds the threshold, Buzzer ON for 5 seconds
\n
"
,
wbgt
);
PWMExport
(
PWM_PIN
);
PWMWritePeriod
(
PWM_PIN
,
20000000
);
PWMWriteDutyCycle
(
PWM_PIN
,
0
);
PWMEnable
(
PWM_PIN
);
if
(
PWMWriteDutyCycle
(
PWM_PIN
,
20000000
)
==
-
1
)
// 100% 듀티 사이클
{
fprintf
(
stderr
,
"Failed to write duty cycle
\n
"
);
}
sleep
(
5
);
// 5초 동안 부저 울림
if
(
PWMWriteDutyCycle
(
PWM_PIN
,
0
)
==
-
1
)
{
fprintf
(
stderr
,
"Failed to write duty cycle
\n
"
);
}
}
// 플래그 리셋
temp_data_received
=
0
;
light_data_received
=
0
;
}
}
int
main
()
{
int
server_sock
;
struct
sockaddr_in
server_addr
;
int
opt
=
1
;
// 소켓 생성
server_sock
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
);
if
(
server_sock
==
-
1
)
{
perror
(
"socket creation failed"
);
exit
(
EXIT_FAILURE
);
}
// SO_REUSEADDR 옵션 설정
if
(
setsockopt
(
server_sock
,
SOL_SOCKET
,
SO_REUSEADDR
,
&
opt
,
sizeof
(
opt
)))
{
perror
(
"setsockopt failed"
);
close
(
server_sock
);
exit
(
EXIT_FAILURE
);
}
// 서버 주소 초기화
memset
(
&
server_addr
,
0
,
sizeof
(
server_addr
));
server_addr
.
sin_family
=
AF_INET
;
server_addr
.
sin_port
=
htons
(
SERVER_PORT
);
server_addr
.
sin_addr
.
s_addr
=
INADDR_ANY
;
// 소켓 바인딩
if
(
bind
(
server_sock
,
(
struct
sockaddr
*
)
&
server_addr
,
sizeof
(
server_addr
))
==
-
1
)
{
perror
(
"socket bind failed"
);
close
(
server_sock
);
exit
(
EXIT_FAILURE
);
}
// 연결 대기
if
(
listen
(
server_sock
,
5
)
==
-
1
)
{
perror
(
"listen failed"
);
close
(
server_sock
);
exit
(
EXIT_FAILURE
);
}
printf
(
"Server is listening on port %d
\n
"
,
SERVER_PORT
);
// GPIO 초기화
if
(
GPIOExport
(
POUT
)
==
-
1
)
{
return
1
;
}
// GPIO 방향 설정 (출력으로 설정)
if
(
GPIODirection
(
POUT
,
1
)
==
-
1
)
{
return
2
;
}
// PWM 초기화
if
(
PWMExport
(
PWM_PIN
)
==
-
1
)
{
return
3
;
}
// PWM 주기 설정 (20ms 주기)
if
(
PWMWritePeriod
(
PWM_PIN
,
20000000
)
==
-
1
)
{
return
4
;
}
while
(
1
)
{
struct
sockaddr_in
client_addr
;
socklen_t
client_addr_len
=
sizeof
(
client_addr
);
int
*
client_sock
=
malloc
(
sizeof
(
int
));
*
client_sock
=
accept
(
server_sock
,
(
struct
sockaddr
*
)
&
client_addr
,
&
client_addr_len
);
if
(
*
client_sock
==
-
1
)
{
perror
(
"server accept failed"
);
free
(
client_sock
);
// 메모리 누수 수정
continue
;
}
pthread_t
tid
;
if
(
pthread_create
(
&
tid
,
NULL
,
handle_client
,
client_sock
)
!=
0
)
{
perror
(
"pthread_create failed"
);
free
(
client_sock
);
// 메모리 누수 수정
}
pthread_detach
(
tid
);
}
// 소켓 종료
close
(
server_sock
);
// GPIO 해제
GPIOUnexport
(
POUT
);
// PWM 해제
FILE
*
fp
=
fopen
(
"/sys/class/pwm/pwmchip0/unexport"
,
"w"
);
if
(
fp
!=
NULL
)
{
fprintf
(
fp
,
"%d"
,
PWM_PIN
);
fclose
(
fp
);
}
return
0
;
}
int
GPIOExport
(
int
pin
){
char
buffer
[
BUFFER_MAX
];
ssize_t
bytes_written
;
int
fd
;
fd
=
open
(
"/sys/class/gpio/export"
,
O_WRONLY
);
if
(
-
1
==
fd
){
fprintf
(
stderr
,
"Failed to open export for writing!
\n
"
);
return
-
1
;
}
bytes_written
=
snprintf
(
buffer
,
BUFFER_MAX
,
"%d"
,
pin
);
write
(
fd
,
buffer
,
bytes_written
);
close
(
fd
);
return
0
;
}
int
GPIODirection
(
int
pin
,
int
dir
){
static
const
char
s_directions_str
[]
=
"in
\0
out"
;
char
path
[
DIRECTION_MAX
]
=
"/sys/class/gpio/gpio%d/direction"
;
int
fd
;
snprintf
(
path
,
DIRECTION_MAX
,
"/sys/class/gpio/gpio%d/direction"
,
pin
);
fd
=
open
(
path
,
O_WRONLY
);
if
(
-
1
==
fd
){
fprintf
(
stderr
,
"Failed to open gpio direction for writing!
\n
"
);
return
-
1
;
}
if
(
-
1
==
write
(
fd
,
&
s_directions_str
[
IN
==
dir
?
0
:
3
],
IN
==
dir
?
2
:
3
)){
fprintf
(
stderr
,
"Failed to set direction!
\n
"
);
close
(
fd
);
return
-
1
;
}
close
(
fd
);
return
0
;
}
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
[
LOW
==
value
?
0
:
1
],
1
)){
fprintf
(
stderr
,
"Failed to write value!
\n
"
);
close
(
fd
);
return
-
1
;
}
close
(
fd
);
return
0
;
}
int
GPIORead
(
int
pin
){
char
path
[
VALUE_MAX
];
char
value_str
[
3
];
int
fd
;
snprintf
(
path
,
VALUE_MAX
,
"/sys/class/gpio/gpio%d/value"
,
pin
);
fd
=
open
(
path
,
O_RDONLY
);
if
(
-
1
==
fd
){
fprintf
(
stderr
,
"Failed to open gpio value for reading!
\n
"
);
return
-
1
;
}
if
(
-
1
==
read
(
fd
,
value_str
,
3
)){
fprintf
(
stderr
,
"Failed to read value!
\n
"
);
close
(
fd
);
return
-
1
;
}
close
(
fd
);
return
(
atoi
(
value_str
));
}
int
GPIOUnexport
(
int
pin
){
char
buffer
[
BUFFER_MAX
];
ssize_t
bytes_written
;
int
fd
;
fd
=
open
(
"/sys/class/gpio/unexport"
,
O_WRONLY
);
if
(
-
1
==
fd
){
fprintf
(
stderr
,
"Failed to open unexport for writing!
\n
"
);
return
-
1
;
}
bytes_written
=
snprintf
(
buffer
,
BUFFER_MAX
,
"%d"
,
pin
);
write
(
fd
,
buffer
,
bytes_written
);
close
(
fd
);
return
0
;
}
int
PWMExport
(
int
pwmnum
){
char
buffer
[
BUFFER_MAX
];
int
bytes_written
;
int
fd
;
fd
=
open
(
"/sys/class/pwm/pwmchip0/unexport"
,
O_WRONLY
);
if
(
-
1
==
fd
){
fprintf
(
stderr
,
"Failed to open in unexport!
\n
"
);
return
-
1
;
}
bytes_written
=
snprintf
(
buffer
,
BUFFER_MAX
,
"%d"
,
pwmnum
);
write
(
fd
,
buffer
,
bytes_written
);
close
(
fd
);
sleep
(
1
);
fd
=
open
(
"/sys/class/pwm/pwmchip0/export"
,
O_WRONLY
);
if
(
-
1
==
fd
){
fprintf
(
stderr
,
"Failed to open in export!
\n
"
);
return
-
1
;
}
bytes_written
=
snprintf
(
buffer
,
BUFFER_MAX
,
"%d"
,
pwmnum
);
write
(
fd
,
buffer
,
bytes_written
);
close
(
fd
);
sleep
(
1
);
return
0
;
}
int
PWMEnable
(
int
pwmnum
){
static
const
char
s_unenable_str
[]
=
"0"
;
static
const
char
s_enable_str
[]
=
"1"
;
char
path
[
DIRECTION_MAX
];
int
fd
;
snprintf
(
path
,
DIRECTION_MAX
,
"/sys/class/pwm/pwmchip0/pwm%d/enable"
,
pwmnum
);
// agian to check
fd
=
open
(
path
,
O_WRONLY
);
if
(
-
1
==
fd
){
fprintf
(
stderr
,
"Failed to open in enable!
\n
"
);
return
-
1
;
}
write
(
fd
,
s_unenable_str
,
strlen
(
s_unenable_str
));
close
(
fd
);
fd
=
open
(
path
,
O_WRONLY
);
if
(
-
1
==
fd
){
fprintf
(
stderr
,
"Failed to open in enable!
\n
"
);
return
-
1
;
}
write
(
fd
,
s_enable_str
,
strlen
(
s_enable_str
));
close
(
fd
);
return
0
;
}
int
PWMWritePeriod
(
int
pwmnum
,
int
value
){
char
s_values_str
[
VALUE_MAX
];
char
path
[
VALUE_MAX
];
int
fd
,
byte
;
snprintf
(
path
,
VALUE_MAX
,
"/sys/class/pwm/pwmchip0/pwm%d/period"
,
pwmnum
);
//check again
fd
=
open
(
path
,
O_WRONLY
);
if
(
-
1
==
fd
){
fprintf
(
stderr
,
"Failed to open in period!
\n
"
);
return
-
1
;
}
byte
=
snprintf
(
s_values_str
,
VALUE_MAX
,
"%d"
,
value
);
//check again
if
(
-
1
==
write
(
fd
,
s_values_str
,
byte
)){
fprintf
(
stderr
,
"Failed to write value in period!
\n
"
);
close
(
fd
);
return
-
1
;
}
close
(
fd
);
return
0
;
}
int
PWMWriteDutyCycle
(
int
pwmnum
,
int
value
){
char
path
[
VALUE_MAX
];
char
s_values_str
[
VALUE_MAX
];
int
fd
,
byte
;
snprintf
(
path
,
VALUE_MAX
,
"/sys/class/pwm/pwmchip0/pwm%d/duty_cycle"
,
pwmnum
);
//check this again
fd
=
open
(
path
,
O_WRONLY
);
if
(
-
1
==
fd
){
fprintf
(
stderr
,
"Faided to open in duty_cycle!
\n
"
);
return
-
1
;
}
byte
=
snprintf
(
s_values_str
,
VALUE_MAX
,
"%d"
,
value
);
//check this again
if
(
-
1
==
write
(
fd
,
s_values_str
,
byte
)){
fprintf
(
stderr
,
"Failed to write value! in duty_cycle
\n
"
);
close
(
fd
);
return
-
1
;
}
close
(
fd
);
return
0
;
}
\ No newline at end of file
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