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
GitLab community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
서현 박
System Programming
Merge requests
!1
myeongha_code
Code
Review changes
Check out branch
Download
Patches
Plain diff
Expand sidebar
Merged
myeongha_code
myeonghaJoo/system-programming:main
into
main
Overview
1
Commits
1
Pipelines
0
Changes
1
Merged
Joo myeongha
requested to merge
myeonghaJoo/system-programming:main
into
main
1 year ago
Overview
1
Commits
1
Pipelines
0
Changes
1
myeongha_code
0
0
Merge request reports
Compare
main
main (base)
and
latest version
latest version
34c153ed
1 commit,
1 year ago
1 file
+
386
−
0
Inline
Compare changes
Side-by-side
Inline
Show whitespace changes
Show one file at a time
lcdController.c
0 → 100644
+
386
−
0
View file @ 34c153ed
Edit in single-file editor
Open in Web IDE
#include
<arpa/inet.h>
#include
<fcntl.h>
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>
#include
<sys/socket.h>
#include
<sys/types.h>
#include
<unistd.h>
#include
<pthread.h>
#include
<wiringPi.h>
#include
<wiringPiI2C.h>
#include
<wiringPi.h>
#include
<stdbool.h>
#define I2C_ADDR 0x27 // LCD 주소
#define LCD_CHR 1 // Mode - Sending data
#define LCD_CMD 0 // Mode - Sending command
#define LINE1 0x80 // 첫번째 줄
#define LINE2 0xC0 // 두번째 줄
#define LCD_BACKLIGHT 0x08 // On
// LCD_BACKLIGHT = 0x00 # Off
#define ENABLE 0b00000100 // Enable bit
#define MSG_SIZE 1024
#define IN 0
#define OUT 1
#define PWM 0
#define LOW 0
#define HIGH 1
#define VALUE_MAX 256
#define DIRECTION_MAX 256
void
lcd_init
(
void
);
void
lcd_byte
(
int
bits
,
int
mode
);
void
lcd_toggle_enable
(
int
bits
);
void
lcdLoc
(
int
line
);
//move cursor
void
ClrLcd
(
void
);
// clr LCD return home
void
typeln
(
const
char
*
s
);
int
fd
;
// seen by all subroutines
char
msg
[
MSG_SIZE
]
=
{
0
};
char
tempMsg
[
MSG_SIZE
]
=
{
0
};
static
int
PWMExport
(
int
pwmnum
)
{
#define BUFFER_MAX 3
char
buffer
[
BUFFER_MAX
];
int
fd
,
byte
;
fd
=
open
(
"/sys/class/pwm/pwmchip0/export"
,
O_WRONLY
);
if
(
-
1
==
fd
)
{
fprintf
(
stderr
,
"Failed to open export for export!
\n
"
);
return
(
-
1
);
}
byte
=
snprintf
(
buffer
,
BUFFER_MAX
,
"%d"
,
pwmnum
);
write
(
fd
,
buffer
,
byte
);
close
(
fd
);
sleep
(
1
);
return
(
0
);
}
static
int
PWMEnable
(
int
pwmnum
)
{
static
const
char
s_enable_str
[]
=
"1"
;
char
path
[
DIRECTION_MAX
];
int
fd
;
snprintf
(
path
,
DIRECTION_MAX
,
"/sys/class/pwm/pwmchip0/pwm0/enable"
,
pwmnum
);
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
);
}
static
int
PWMWritePeriod
(
int
pwmnum
,
int
value
)
{
char
s_value_str
[
VALUE_MAX
];
char
path
[
VALUE_MAX
];
int
fd
,
byte
;
snprintf
(
path
,
VALUE_MAX
,
"/sys/class/pwm/pwmchip0/pwm0/period"
,
pwmnum
);
fd
=
open
(
path
,
O_WRONLY
);
if
(
-
1
==
fd
)
{
fprintf
(
stderr
,
"Failed to open in period!
\n
"
);
return
(
-
1
);
}
byte
=
snprintf
(
s_value_str
,
VALUE_MAX
,
"%d"
,
value
);
if
(
-
1
==
write
(
fd
,
s_value_str
,
byte
))
{
fprintf
(
stderr
,
"Failed to write value in period!
\n
"
);
close
(
fd
);
return
-
1
;
}
close
(
fd
);
return
(
0
);
}
static
int
PWMWriteDutyCycle
(
int
pwmnum
,
int
value
)
{
char
s_value_str
[
VALUE_MAX
];
char
path
[
VALUE_MAX
];
int
fd
,
byte
;
snprintf
(
path
,
VALUE_MAX
,
"/sys/class/pwm/pwmchip0/pwm0/duty_cycle"
,
pwmnum
);
fd
=
open
(
path
,
O_WRONLY
);
if
(
-
1
==
fd
)
{
fprintf
(
stderr
,
"Failed to open in duty cycle!
\n
"
);
return
(
-
1
);
}
byte
=
snprintf
(
s_value_str
,
VALUE_MAX
,
"%d"
,
value
);
if
(
-
1
==
write
(
fd
,
s_value_str
,
byte
))
{
fprintf
(
stderr
,
"Failed to write value in duty cycle!
\n
"
);
close
(
fd
);
return
-
1
;
}
close
(
fd
);
return
(
0
);
}
void
error_handling
(
char
*
message
)
{
fputs
(
message
,
stderr
);
fputc
(
'\n'
,
stderr
);
exit
(
1
);
}
//lcd thread
void
*
lcd
(
void
*
data
)
{
int
str_len
=
0
;
int
sock
=
*
((
int
*
)
data
);
bool
isS
=
true
;
if
(
wiringPiSetup
()
==
-
1
)
exit
(
1
);
fd
=
wiringPiI2CSetup
(
I2C_ADDR
);
lcd_init
();
// setup LCD
char
*
sleepMode1
=
"Sleep Mode On"
;
char
*
sleepMode2
=
"Go to dreamland"
;
char
*
wakeUpMode1
=
"Wake up !!!"
;
char
*
wakeUpMode2
=
"Out of dreamland"
;
char
*
motion1
=
"Motion Count"
;
char
motion2
[
100
]
=
"Total : "
;
while
(
1
){
if
(
strcmp
(
"s"
,
msg
)
==
0
&&
isS
){
// 수면모드 on
printf
(
"수면모드 on
\n
"
);
ClrLcd
();
lcdLoc
(
LINE1
);
typeln
(
sleepMode1
);
lcdLoc
(
LINE2
);
typeln
(
sleepMode2
);
isS
=
false
;
}
if
(
strcmp
(
"e"
,
msg
)
==
0
){
// 수면 모드 off
printf
(
"수면모드 off
\n
"
);
ClrLcd
();
lcdLoc
(
LINE1
);
typeln
(
wakeUpMode1
);
lcdLoc
(
LINE2
);
typeln
(
wakeUpMode2
);
// motion number display
str_len
=
read
(
sock
,
msg
,
sizeof
(
msg
));
// 다시 서버로부터 메세지 기다림
if
(
str_len
==
-
1
)
error_handling
(
"read() error"
);
if
(
str_len
==
0
)
break
;
printf
(
"motion num: %s
\n
"
,
msg
);
strcat
(
motion2
,
msg
);
ClrLcd
();
lcdLoc
(
LINE1
);
typeln
(
motion1
);
lcdLoc
(
LINE2
);
typeln
(
motion2
);
delay
(
7000
);
ClrLcd
();
PWMWriteDutyCycle
(
PWM
,
0
);
break
;
}
}
}
//led thread
void
*
led
(
void
*
data
)
{
int
sock
=
*
((
int
*
)
data
);
int
str_len
=
0
;
int
rsCount
=
0
;
bool
isRs1
=
true
;
bool
isRs2
=
true
;
bool
isS
=
true
;
bool
isRe
=
true
;
while
(
1
)
{
if
(
strcmp
(
"rs1"
,
msg
)
==
0
&&
isRs1
){
// 첫번째 rs
printf
(
"첫번째 rs1
\n
"
);
PWMWriteDutyCycle
(
PWM
,
4500000
);
isRs1
=
false
;
}
else
if
(
strcmp
(
"rs2"
,
msg
)
==
0
&&
isRs2
){
// 두번째 rs
printf
(
"두번째 rs2
\n
"
);
PWMWriteDutyCycle
(
PWM
,
1000000
);
isRs2
=
false
;
}
if
(
strcmp
(
"s"
,
msg
)
==
0
&&
isS
){
//수면모드
printf
(
"수면모드
\n
"
);
PWMWriteDutyCycle
(
PWM
,
0
);
isS
=
false
;
}
if
(
strcmp
(
"re"
,
msg
)
==
0
&&
isRe
){
//기상 준비
printf
(
"기상준비
\n
"
);
for
(
int
i
=
0
;
i
<
10000
;
i
++
)
{
// 3초동안 불서서히 켜짐
PWMWriteDutyCycle
(
PWM
,
i
*
1000
);
usleep
(
300
);
}
isRe
=
false
;
}
if
(
strcmp
(
"e"
,
msg
)
==
0
){
// 종료
PWMWriteDutyCycle
(
PWM
,
10000000
);
printf
(
"기상
\n
"
);
break
;
}
}
}
int
main
(
int
argc
,
char
*
argv
[])
{
pthread_t
p_thread
[
2
];
int
thr_id
;
int
status
;
int
sock
;
struct
sockaddr_in
serv_addr
;
int
str_len
;
PWMExport
(
PWM
);
PWMWritePeriod
(
PWM
,
10000000
);
PWMWriteDutyCycle
(
PWM
,
10000000
);
PWMEnable
(
PWM
);
if
(
argc
!=
3
)
{
printf
(
"Usage : %s <IP> <port>
\n
"
,
argv
[
0
]);
exit
(
1
);
}
// sockt create
sock
=
socket
(
PF_INET
,
SOCK_STREAM
,
0
);
if
(
sock
==
-
1
)
error_handling
(
"socket() error"
);
// config server info
memset
(
&
serv_addr
,
0
,
sizeof
(
serv_addr
));
serv_addr
.
sin_family
=
AF_INET
;
serv_addr
.
sin_addr
.
s_addr
=
inet_addr
(
argv
[
1
]);
serv_addr
.
sin_port
=
htons
(
atoi
(
argv
[
2
]));
// connect request to server
if
(
connect
(
sock
,
(
struct
sockaddr
*
)
&
serv_addr
,
sizeof
(
serv_addr
))
==
-
1
)
error_handling
(
"connect() error"
);
printf
(
"서버와 연결
\n
"
);
//각 기능에 맞게 스레드 형성
thr_id
=
pthread_create
(
&
p_thread
[
0
],
NULL
,
led
,
(
void
*
)
&
sock
);
if
(
thr_id
<
0
)
{
perror
(
"thread create error : "
);
exit
(
0
);
}
thr_id
=
pthread_create
(
&
p_thread
[
1
],
NULL
,
lcd
,
(
void
*
)
&
sock
);
if
(
thr_id
<
0
)
{
perror
(
"thread create error : "
);
exit
(
0
);
}
memset
(
tempMsg
,
0
,
sizeof
(
tempMsg
));
memset
(
msg
,
0
,
sizeof
(
msg
));
while
(
1
){
str_len
=
read
(
sock
,
tempMsg
,
sizeof
(
tempMsg
));
printf
(
"tempMsg: %s
\n
"
,
tempMsg
);
strcpy
(
msg
,
tempMsg
);
if
(
str_len
==
-
1
)
error_handling
(
"read() error"
);
if
(
str_len
==
0
)
break
;
// 서버가 닫히면 클라이언트도 종료
if
(
strcmp
(
"e"
,
msg
)
==
0
)
break
;
}
pthread_join
(
p_thread
[
0
],
(
void
**
)
&
status
);
pthread_join
(
p_thread
[
1
],
(
void
**
)
&
status
);
close
(
sock
);
return
0
;
}
// clr lcd go home loc 0x80
void
ClrLcd
(
void
)
{
lcd_byte
(
0x01
,
LCD_CMD
);
lcd_byte
(
0x02
,
LCD_CMD
);
}
// go to location on LCD
void
lcdLoc
(
int
line
)
{
lcd_byte
(
line
,
LCD_CMD
);
}
// this allows use of any size string
void
typeln
(
const
char
*
s
)
{
while
(
*
s
)
lcd_byte
(
*
(
s
++
),
LCD_CHR
);
}
void
lcd_byte
(
int
bits
,
int
mode
)
{
//Send byte to data pins
// bits = the data
// mode = 1 for data, 0 for command
int
bits_high
;
int
bits_low
;
// uses the two half byte writes to LCD
bits_high
=
mode
|
(
bits
&
0xF0
)
|
LCD_BACKLIGHT
;
bits_low
=
mode
|
((
bits
<<
4
)
&
0xF0
)
|
LCD_BACKLIGHT
;
// High bits
wiringPiI2CReadReg8
(
fd
,
bits_high
);
lcd_toggle_enable
(
bits_high
);
// Low bits
wiringPiI2CReadReg8
(
fd
,
bits_low
);
lcd_toggle_enable
(
bits_low
);
}
void
lcd_toggle_enable
(
int
bits
)
{
// Toggle enable pin on LCD display
delayMicroseconds
(
500
);
wiringPiI2CReadReg8
(
fd
,
(
bits
|
ENABLE
));
delayMicroseconds
(
500
);
wiringPiI2CReadReg8
(
fd
,
(
bits
&
~
ENABLE
));
delayMicroseconds
(
500
);
}
void
lcd_init
()
{
// Initialise display
lcd_byte
(
0x33
,
LCD_CMD
);
// Initialise
lcd_byte
(
0x32
,
LCD_CMD
);
// Initialise
lcd_byte
(
0x06
,
LCD_CMD
);
// Cursor move direction
lcd_byte
(
0x0C
,
LCD_CMD
);
// 0x0F On, Blink Off
lcd_byte
(
0x28
,
LCD_CMD
);
// Data length, number of lines, font size
lcd_byte
(
0x01
,
LCD_CMD
);
// Clear display
delayMicroseconds
(
500
);
}
\ No newline at end of file
Loading