반응형

사전 지식

아두이노 servo모터 제어

https://developmentdiary.tistory.com/508

라즈베리파이 - 아두이노 블루투스 통신

https://developmentdiary.tistory.com/509

안드로이드-라즈베리파이 소켓통신

https://developmentdiary.tistory.com/510




아두이노 세팅

사용할 핀은 각자 정하면된다.아두이노 나노를 통해 제어한다면 공간적인 측면이나 전력 측면에서 조금 유리할 것이다.


회로도

https://developmentdiary.tistory.com/508


아래 핀이나 각도는 자신의 환경에 맞게 세팅하면된다.

핀을 바꿀시 핀연결에 맞게 회로도 바꾸어주어야한다.


코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <SoftwareSerial.h>   //소프트웨어시리얼 라이브러리 불러오기
#include<Servo.h>//서보 라이브러리 추가
SoftwareSerial BTSerial(3,2); //블루투스 센서 초기화 TX,RX
//RXD=아두이노 2번핀에 연결    
//TXD=아두이노 3번핀에 연결
 
 
Servo servo;//서보 객체생성
 
int value=90;//각도 변수
 
 
void setup() {
  BTSerial.begin(9600);//블루투스 시리얼통신 속도 맞추기
  servo.attach(7);//7번핀으로 모터 제어
}
 
void loop() {
  if(BTSerial.available())//블루투스로 데이터를 받았다면
  {
    char in_data;
    in_data=(char)BTSerial.read();
    if(in_data=='1')
    {
      value=30;//켜기
    }
    else if(in_data=='2'){
      value=150;//끄기
    }
  }
  servo.write(value);
  delay(1000);
  value=90;
  servo.write(value);
  delay(1000);
}

cs



라즈베리파이 세팅

라즈베리파이에는 서버가 들어간다.

안드로이드를 통해 소켓으로 데이터를 받으면 데이터를 판별해 블루투스 통신을 통해 아두이노를 제어한다.

아두이노와의 블루투스 통신은 python을 통해 만들었고 소켓 서버는 java 로 만들었다.

java소켓을 통해 데이터를 받으면 shell script를 통해 실행하도록 구현하였다.

모두 python으로 구현해도 되지만 앞서 배운것들을 많이 활용할 수 있도록 하였다. 또한 구조를 좀 더 쉽게 파악 할 수 있도록 해보았다. 복잡해 보일수도 있어서 추후 python을 통한 소켓통신을 통해 하나의 파일로 만들어 볼 생각이다.



turnOn.py(블루투스통신을 통해 아두이노 제어)

블루투스 mac주소는 각자 수정해주자

1
2
3
4
5
6
from bluetooth import *
 
client_socket=BluetoothSocket( RFCOMM )
client_socket.connect(("FF:FF:FF:FF:FF:FF"1))
client_socket.send('1')
client_socket.close()
cs



turnOff.py(블루투스 통신을 통해 아두이노 제어)

블루투스 mac주소는 각자 수정해주자

1
2
3
4
5
6
from bluetooth import *
 
client_socket=BluetoothSocket( RFCOMM )
client_socket.connect(("FF:FF:FF:FF:FF:FF"1))
client_socket.send('2')
client_socket.close()
cs



lightTurnOn.sh(쉘스크립트를 통해 자바에서 파이썬 파일 실행)

python파일의 경로를 각자 바꿔주자

1
2
3
#!/bin/bash
python /home/pi/adu/turnOn.py
 

cs



lightTurnOff.sh(쉘스크립트를 통해 자바에서 파이썬 파일 실행)

python파일의 경로를 각자 바꿔주자

1
2
3
#!/bin/bash
python /home/pi/adu/turnOff.py
 

cs



SocketServer.java(휴대폰에서 받은 소켓통신 데이터에 따라 shell script실행)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
 
 
 
public class SocketServer implements Runnable {
    public static final int ServerPort = 22222;//포트 선택
    @Override
    public void run() {
        try {
            
            ServerSocket serverSocket = new ServerSocket(ServerPort);//소켓생성
            System.out.println("Connecting...");
            while (true) {
                //client 접속 대기
                Socket client = serverSocket.accept(); //데이터 전송 감지
                try {
 
                    //client data 수신                    
                    //소켓에서 넘오는 stream 형태의 문자를 얻은 후 읽어 들어서  bufferstream 형태로 in 에 저장.                                                                                           
                    BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
                    //in에 저장된 데이터를 String 형태로 변환 후 읽어들어서 String에 저장
                    String str = in.readLine();
                    String command= "";
                    //client에 다시 전송
                    if(str.equals("")||str==null) {//빈문자열을 보냈을때 앱에서도 막아야될듯
                        continue;
                    }
                    PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(client.getOutputStream())), true);
                    out.println("Server Received : '" + str + "'");
                    
                    if(str.equals("turnOn")) {
                        command = "/home/pi/shellCode/lightTurnOn.sh";//쉘코드 주소 수정해주자
                    }else if(str.equals("turnOff")) {
                        command = "/home/pi/shellCode/lightTurnOff.sh";
                    }else {
                        continue;
                    }
                    try{
                        Process ps = Runtime.getRuntime().exec(command);
                        ps.waitFor();
                        //System.out.println(ps.exitValue());
                        ps.destroy();
                    }catch(Exception e){
                        e.printStackTrace();
                    }
                                                        
 
                } catch (Exception e) {//데이터 전송과정에서의 에러출력
                    System.out.println("Error");
                    e.printStackTrace();
                } finally {//소켓 연결 종료
                    client.close();        
                }
            }
 
        } catch (Exception e) {//연결 과정에서의 에러출력
            System.out.println("S: Error");
            e.printStackTrace();
        }
 
    }
 
    public static void main(String[] args) {
 
        Thread ServerThread = new Thread(new SocketServer());//Thread로 실행
        ServerThread.start();//서버 실행
 
    }
 
}

cs





안드로이드 세팅

버튼에 따라 메세지를 전달하게 만들었고 여러버튼을 미리 만들어 두었다.

응용하여 써보면 공부나 실생활 측면에서 많은 도움이될거같다.


.java

서버의 ip와 포트에 맞게 수정해주자


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package com.example.myapplication;
 
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.TextView;
 
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
 
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
 
 
 
public class MainActivity extends AppCompatActivity {
 
    private Handler mHandler;
    Socket socket;
    private String ip = "1.1.1.1"// IP 주소
    private int port = 9999// PORT번호
    EditText inputText;
    TextView logText;
 
    @Override
    protected void onStop() {
        super.onStop();
        try {
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        mHandler = new Handler();
        inputText = (EditText) findViewById(R.id.inputEditText);
        Button sendMsgButton = (Button) findViewById(R.id.sendMsgButton);
        Button turnOnLightButton=(Button)findViewById(R.id.turnOnLightButton);
        Button turnOffLightButton=(Button)findViewById(R.id.turnOffLightButton);
 
        logText = (TextView)findViewById(R.id.logTextView);
 
        sendMsgButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (inputText.getText().toString() != null || !inputText.getText().toString().equals("")) {
                    buttonThread th =new buttonThread(inputText.getText().toString());
                    th.start();
                }
            }
        });
 
        turnOnLightButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                buttonThread bt=new buttonThread("turnOn");
                bt.start();
            }
        });
 
        turnOffLightButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                buttonThread bt=new buttonThread("turnOff");
                bt.start();
            }
        });
 
    }
 
    class buttonThread extends Thread{
        String msg;
        public buttonThread(String msg){
            this.msg=msg;
        }
 
 
        public void run(){
            try{
                //소켓 생성
                InetAddress serverAddr = InetAddress.getByName(ip);
                socket =  new Socket(serverAddr,port);
                //입력 메시지
                String sndMsg = msg;
                Log.d("=============", sndMsg);
                //데이터 전송
                PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
                out.println(sndMsg);
                //데이터 수신
                BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                String read = input.readLine();
                //화면 출력
                mHandler.post(new msgUpdate(read));
                Log.d("=============", read);
                socket.close();
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
    // 받은 메시지 출력
    class msgUpdate implements Runnable {
        private String msg;
        public msgUpdate(String str) {
            this.msg = str;
        }
        public void run() {
            logText.setText(logText.getText().toString() + msg + "\n");
        }
    };
 
 
 
}
 

cs



.xml(디자인)

버튼을 많이 만들어두었다.

나중에 활용해보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
 
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:layout_constraintTop_toTopOf="parent"
        tools:layout_editor_absoluteX="8dp"
        android:weightSum="5"
        >
 
        <LinearLayout
            android:layout_weight="1"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:orientation="horizontal"
            android:weightSum="2">
 
            <Button
                android:id="@+id/turnOnLightButton"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="불 켜기" />
 
            <Button
                android:id="@+id/turnOffLightButton"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="불 끄기" />
        </LinearLayout>
 
        <LinearLayout
            android:layout_weight="1"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:orientation="horizontal"
            android:weightSum="2">
 
            <Button
                android:id="@+id/button8"
                android:layout_height="match_parent"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="Button" />
 
            <Button
                android:id="@+id/button7"
                android:layout_height="match_parent"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="Button"/>
        </LinearLayout>
 
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="horizontal"
            android:weightSum="2">
 
            <Button
                android:id="@+id/button10"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="Button" />
 
            <Button
                android:id="@+id/button9"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="Button" />
        </LinearLayout>
 
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="0.5"
            android:orientation="horizontal">
 
            <EditText
                android:id="@+id/inputEditText"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1.5"
                app:layout_constraintStart_toStartOf="parent"
                tools:layout_editor_absoluteY="301dp" />
 
            <Button
                android:id="@+id/sendMsgButton"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="0.5"
                android:text="Send" />
        </LinearLayout>
 
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1.5"
            android:orientation="horizontal">
 
            <ScrollView
                android:id="@+id/logView"
                android:layout_width="match_parent"
                android:layout_height="match_parent">
 
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:orientation="vertical">
 
                    <TextView
                        android:id="@+id/logTextView"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent" />
                </LinearLayout>
            </ScrollView>
 
 
        </LinearLayout>
    </LinearLayout>
 
</android.support.constraint.ConstraintLayout>

cs


Manifest.xml

역시 인터넷 사용권한을 추가해주자.


1
   <uses-permission android:name="android.permission.INTERNET" />
cs




아두이노,라즈베리파이,안드로이드 세팅해 줄게 너무많다. 이런 세팅에 작은 오류들을 수정한다고 힘들었다.

그냥 걸어가서 불켜고 불끄면 되는것을 이렇게 만들어 보았다. 설치 또한 힘들거나 불가능 할 수 있는데도 말이다. 하지만 응용하면 활용도는 무궁무진할것이다.

이것을 토대로 집안 여러가지 제품들을 침대에 누워서 또는 밖에서도 통제해 본다면 조금 더 나아진 삶이 되지않을까...다음 프로젝트는 음성인식을 통해서 제어할 수 있도록 만들어 볼 생각이다.



반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기