diff --git a/pi3/data.json b/pi3/data.json
new file mode 100644
index 0000000000000000000000000000000000000000..419b1ba44a4939b10e1d1c1396238630e1eb73ff
--- /dev/null
+++ b/pi3/data.json
@@ -0,0 +1 @@
+{"Humid": 82, "Light": 423, "Rain": 1, "Temp": 25, "Trash": 19}
\ No newline at end of file
diff --git a/pi3/fileRead.py b/pi3/fileRead.py
new file mode 100644
index 0000000000000000000000000000000000000000..a60fc4cb031db847506870c88e8d1bfd0c7f1fe7
--- /dev/null
+++ b/pi3/fileRead.py
@@ -0,0 +1,11 @@
+from firebase import firebase
+import json
+
+firebase_url = 'https://testing-in-rpi-default-rtdb.asia-southeast1.firebasedatabase.app/'
+
+firebase = firebase.FirebaseApplication(firebase_url, None)
+
+# data.json에 읽어온 값 저장
+result = firebase.get('/', None)
+with open('./data.json', 'w') as file:
+    json.dump(result, file)
diff --git a/pi3/fileReadAnother b/pi3/fileReadAnother
new file mode 100644
index 0000000000000000000000000000000000000000..9fbc9079e003cf946fb21f38394a2ada05b36195
--- /dev/null
+++ b/pi3/fileReadAnother
@@ -0,0 +1,12 @@
+from firebase import firebase
+import json
+
+firebase_url = 'https://my-weather-rpi-default-rtdb.asia-southeast1.firebasedatabase.app/'
+
+firebase = firebase.FirebaseApplication(firebase_url, None)
+
+result = firebase.get('/', None)
+
+with open('./data.json', 'w') as file:
+    json.dump(result, file)
+    
\ No newline at end of file
diff --git a/pi3/pi3.c b/pi3/pi3.c
new file mode 100644
index 0000000000000000000000000000000000000000..b2111e1d601e0f9bcdecec94cba20ee01df7fd04
--- /dev/null
+++ b/pi3/pi3.c
@@ -0,0 +1,619 @@
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <pthread.h>
+#include <linux/i2c-dev.h>
+#include <sys/ioctl.h>
+#include <pthread.h>
+#include <jansson.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <wiringPi.h>
+#include <wiringPiI2C.h>
+#include <lcd.h>
+
+#define LCD_ADDR 0x3f // LCD의 I2C 주소
+#define LCD_ROWS 2    // LCD 행 수
+#define LCD_COLS 16   // LCD 열 수
+
+// ------------- LCD -------------
+
+#define BUFFER_MAX 3
+#define DIRECTION_MAX 45
+#define MAX_OUTPUT_LENGTH 256
+
+#define SERVO_ON    350000
+#define SERVO_OFF   2500000
+
+#define PHTCriticalPoint 340
+#define IN 0
+#define OUT 1 
+#define Button 21
+
+#define LOW 0
+#define HIGH 1
+#define VALUE_MAX 256
+
+/*
+    Json 관련 struct
+*/
+typedef struct {
+    int Humid;
+    int Light;
+    int Rain;
+    int Temp;
+} SensorData;
+
+int ReadMode;
+int KMotorValue;
+
+int fd;
+int BLEN=1;
+
+int LcdHumid = 1;
+int LcdLight = 1;
+int LcdRain = 1;
+int LcdTemp = 1;
+
+int pwmnum = 0;  // 사용할 PWM 번호
+int period = 20000000;  // PWM 주기 (나노초 단위)
+
+int toggle = 0; // button toggle 두개의 firebase를 접근하기 위해서
+/*
+    LCD 관련 함수들
+*/
+void write_word(int data){
+    int temp = data;
+    if ( BLEN == 1 )
+        temp |= 0x08;
+    else
+        temp &= 0xF7;
+    wiringPiI2CWrite(fd, temp);
+}
+
+void send_command(int comm){
+    int buf;
+    // Send bit7-4 firstly
+    buf = comm & 0xF0;
+    buf |= 0x04;                    // RS = 0, RW = 0, EN = 1
+    write_word(buf);
+    delay(2);
+    buf &= 0xFB;                    // Make EN = 0
+    write_word(buf);
+
+    // Send bit3-0 secondly
+    buf = (comm & 0x0F) << 4;
+    buf |= 0x04;                    // RS = 0, RW = 0, EN = 1
+    write_word(buf);
+    delay(2);
+    buf &= 0xFB;                    // Make EN = 0
+    write_word(buf);
+}
+
+void send_data(int data){
+    int buf;
+    // Send bit7-4 firstly
+    buf = data & 0xF0;
+    buf |= 0x05;                    // RS = 1, RW = 0, EN = 1
+    write_word(buf);
+    delay(2);
+    buf &= 0xFB;                    // Make EN = 0
+    write_word(buf);
+
+    // Send bit3-0 secondly
+    buf = (data & 0x0F) << 4;
+    buf |= 0x05;                    // RS = 1, RW = 0, EN = 1
+    write_word(buf);
+    delay(2);
+    buf &= 0xFB;                    // Make EN = 0
+    write_word(buf);
+}
+
+void init(){
+    send_command(0x33);     // Must initialize to 8-line mode at first
+    delay(5);
+    send_command(0x32);     // Then initialize to 4-line mode
+    delay(5);
+    send_command(0x28);     // 2 Lines & 5*7 dots
+    delay(5);
+    send_command(0x0C);     // Enable display without cursor
+    delay(5);
+    send_command(0x01);     // Clear Screen
+    wiringPiI2CWrite(fd, 0x08);
+}
+
+void clear(){
+    send_command(0x01);     //clear Screen
+}
+
+void write_l(int x, int y, char data[]){
+    int addr, i;
+    int tmp;
+    if (x < 0)  x = 0;
+    if (x > 15) x = 15;
+    if (y < 0)  y = 0;
+    if (y > 1)  y = 1;
+
+    // Move cursor
+    addr = 0x80 + 0x40 * y + x;
+    send_command(addr);
+
+    tmp = strlen(data);
+    for (i = 0; i < tmp; i++){
+        send_data(data[i]);
+    }
+}
+
+/*
+    PWM 관련 함수들
+*/
+static int PWMExport(int pwmnum){
+    #define BUFFER_MAX 3
+    char buffer[BUFFER_MAX];
+    int bytes_written;
+    int fd;
+
+    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);
+}
+
+static int PWMUnexport(int pwmnum)
+{
+    char buffer[BUFFER_MAX];
+    ssize_t 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);
+    return(0);
+}
+static 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);
+    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;
+}
+
+static int PWMUnable(int pwmnum){
+    static const char s_unable_str[] = "0";
+    char path[DIRECTION_MAX];
+    int fd;
+
+    snprintf(path, DIRECTION_MAX, "/sys/class/pwm/pwmchip0/pwm%d/enable", pwmnum);
+    fd=open(path,O_WRONLY);
+    if(-1==fd){
+        fprintf(stderr, "Failed to open in enable!\n");
+        return -1;
+    }
+
+    write(fd,s_unable_str,strlen(s_unable_str));
+    close(fd);
+    return 0;
+}
+
+static 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);
+    fd=open(path,O_WRONLY);
+    if(-1==fd){
+        fprintf(stderr, "Failed to open in period!\n");
+        return(-1);
+    }
+
+    byte=snprintf(s_values_str,10,"%d",value);
+
+    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);
+}
+
+static 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);
+    fd=open(path,O_WRONLY);
+    if(-1==fd){
+        fprintf(stderr,"Failed to oepn in duty_cycle!\n");
+        return(-1);
+    }
+
+    byte=snprintf(s_values_str, 10,"%d",value);
+
+    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);
+}
+
+/*
+    GPIO 관련 함수들
+*/
+static int GPIOExport(int pin){
+#define BUFFER_MAX 3
+    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);
+}
+
+static 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);
+}
+
+static int GPIODirection(int pin, int dir){
+    static const char s_directions_str[] = "in\nout";
+
+    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);
+}
+
+static 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));
+}
+
+/*
+    Thread 관련 함수들
+*/
+
+void *execute_python(void *arg) {
+    int result;
+    if(toggle){
+        result = system("python3 ./fileReadAnother.py");  
+        printf("Resion0 result\n");
+    }else{
+        result = system("python3 ./fileRead.py");   
+         printf("Resion1 result\n");
+    }
+    if (result == -1) {
+            printf("Failed to execute Python process\n");
+    }
+    return NULL;
+} // python 실행
+
+void* lcdThreadFunction(void* arg) {
+    while (1) {
+        char string[10];
+
+        sprintf(string, "hmd:%d%%", LcdHumid);
+        write_l(0, 0, string);
+        sprintf(string, "rain:%c", (LcdRain % 2 == 0) ? 'X' : 'O');
+        write_l(9, 0, string);
+        sprintf(string, "tmp:%dC", LcdTemp);
+        write_l(0, 1, string);
+        sprintf(string, "pht:%d", LcdLight );
+        write_l(9, 1, string);
+
+        usleep(1000000); // Delay for 1 second
+    }
+} // Lcd print
+
+void *ServoMotorThreadFunction(void *arg){
+    while(1){
+        if( LcdLight >= PHTCriticalPoint)    
+         {
+            if (PWMWriteDutyCycle(pwmnum, SERVO_ON) == -1) {
+                printf("Failed to write PWM duty cycle!\n");
+                break;
+            }
+         }
+        else {
+             if (PWMWriteDutyCycle(pwmnum, SERVO_OFF) == -1) {
+                printf("Failed to write PWM duty cycle!\n");
+                break;
+            }
+        }
+        
+        usleep(1000000); // Delay for 1 second
+    }
+} // servo motor control
+
+void* buttonThreadFunction(void* arg) {
+    while(1)
+    {  
+        if(GPIORead(Button) == 1){
+            printf("GPIORead : Button on\n");
+            toggle = !toggle;
+            printf("Toggle set %d\n",toggle);
+        }
+        usleep(100000);
+    }
+        
+    if(-1 == GPIOUnexport(Button)) return NULL;
+    return NULL;
+} // button control
+
+/*
+    Error 관련 함수
+*/
+
+void error_handling(char *message) {
+    fputs(message, stderr);
+    fputc('\n', stderr);
+    exit(1);
+}
+
+int main(int argc, char *argv[]) {
+    int duty_cycle = 1500000;  // PWM 듀티 사이클 (나노초 단위)
+    
+    // 각 Thread 선언
+    pthread_t python_thread;
+    pthread_t lcdThread; 
+    pthread_t servoThread;
+    pthread_t buttonThread;
+
+    SensorData data;
+    
+    // Socket 통신
+    int sock;
+    struct sockaddr_in serv_addr;
+    
+    fflush(stdout);
+    fflush(stdin);
+    char msg[BUFFER_MAX];
+    memset(msg, 0, sizeof(msg));
+
+    char filename[VALUE_MAX];
+    int str_len;
+    int read_len, sent_len, sent_total;
+    
+    // LCD 관련 설정
+    if (wiringPiSetup() == -1)
+    return 1;
+        
+    fd = wiringPiI2CSetup(LCD_ADDR);
+    init();
+    
+     // PWM 설정
+    if (PWMExport(pwmnum) == -1) {
+        printf("Failed to export PWM!\n");
+        return -1;
+    }
+
+    if (PWMEnable(pwmnum) == -1) {
+        printf("Failed to enable PWM!\n");
+        return -1;
+    }
+
+    if (PWMWritePeriod(pwmnum, period) == -1) {
+        printf("Failed to write PWM period!\n");
+        return -1;
+    }
+
+    // Thread 실행
+    if (pthread_create(&servoThread, NULL, ServoMotorThreadFunction, &pwmnum) != 0) {
+        printf("Failed to create servo control thread!\n");
+        return -1;
+    }
+    if (pthread_create(&buttonThread, NULL, buttonThreadFunction, NULL) != 0) {
+        printf("Failed to create button control thread!\n");
+        return -1;
+    }
+    if (pthread_create(&lcdThread, NULL, lcdThreadFunction, NULL) != 0){
+        printf("Failed to create lcd control thread!\n");
+        return -1;
+    }
+    
+    if (argc != 3) {
+        printf("Usage : %s <IP> <port> \n", argv[0]);
+        exit(1);
+    }
+    
+    // Sock 연결
+    sock = socket(PF_INET, SOCK_STREAM, 0);
+    if (sock == -1)
+        error_handling("socket() error");
+
+    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]));
+
+    if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1)
+        error_handling("connect() error");
+
+    while(1){ // Main loop 시작
+        int thread_create_result = pthread_create(&python_thread, NULL, execute_python, NULL); // python 실행을 위한 thread 실행
+        if (thread_create_result != 0) {
+            printf("Failed to create Python thread\n");
+            return 1;
+        }
+        
+        pthread_join(python_thread, NULL);
+        const char* file_path  = "data.json";
+        // 파일 열기
+        FILE* file = fopen(file_path, "r");
+        if (!file) {
+            printf("Failed to open the file: %s\n", file_path);
+            return 1;
+        }
+        
+        // 파일 크기 확인
+        fseek(file, 0, SEEK_END);
+        long file_size = ftell(file);
+        fseek(file, 0, SEEK_SET);
+
+        // 파일 내용 읽기
+        char* json_content = malloc(file_size + 1);
+        fread(json_content, 1, file_size, file);
+        json_content[file_size] = '\0';
+
+        // 파일 닫기
+        fclose(file);
+
+        json_error_t error;
+        json_t* root = json_loads(json_content, 0, &error);
+        free(json_content);
+
+        if (!root) {
+            printf("Failed to parse the JSON: %s\n", error.text);
+            return 1;
+        }
+        
+        // Json 파일을 읽어서 firebase에서 읽어본 값 unpack
+        json_unpack(root, "{s:i, s:i, s:i, s:i}",
+                    "Humid", &(data.Humid),
+                    "Light", &(data.Light),
+                    "Rain", &(data.Rain),
+                    "Temp", &(data.Temp));
+
+        LcdHumid = data.Humid;
+        LcdLight = data.Light;
+        LcdRain = data.Rain;
+        LcdTemp = data.Temp;
+
+        /*
+            Thread로 PWM으로 모터 제어 (커튼)
+        */
+        
+        printf("Humid: %d\n", LcdHumid);
+        printf("Light: %d\n", LcdLight);
+        printf("Rain: %d\n", LcdRain);
+        printf("Temp: %d\n", LcdTemp);
+        printf("--------------------------------\n");
+    
+        memset(msg, 0, sizeof(msg));
+
+        sprintf(msg, "%d",LcdRain);
+        str_len = write(sock, msg, strlen(msg));
+        if (str_len == -1)
+            error_handling("write() error"); // 보냄
+
+        while ((str_len = read(sock, msg, sizeof(msg))) > 0) {
+                if(str_len == 0) {
+                    error_handling("read() error");
+                }
+                if(msg[0] == '0') break;
+                printf("waiting..\n");
+        } // 잘 받았는지 확인
+
+        str_len = write(sock, "0", 1);
+        if (str_len == -1)
+            error_handling("write() error"); // 잘 받았다고 보냄
+
+        // 메모리 해제
+        json_decref(root);
+        // waiting...
+        usleep(1000 * 1000);
+    }
+
+    // Thread join
+    pthread_join(servoThread, NULL);
+    pthread_join(lcdThread, NULL);
+    pthread_join(buttonThread, NULL);
+
+    return 0;
+}