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
Commits
34c153ed
Commit
34c153ed
authored
1 year ago
by
myeongha
Browse files
Options
Downloads
Patches
Plain Diff
myeongha_code
parent
6a3f957f
No related branches found
No related tags found
1 merge request
!1
myeongha_code
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
lcdController.c
+386
-0
386 additions, 0 deletions
lcdController.c
with
386 additions
and
0 deletions
lcdController.c
0 → 100644
+
386
−
0
View file @
34c153ed
#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
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