<AndroidManifest.xml>

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.joysticktest2">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.JoystickTest2">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

 

<activity_main.xml>

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:id="@+id/linearLayout1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_margin="10dp"
        android:orientation="vertical" >
        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:text="X"
            android:textColor="#444444"
            android:textSize="20dp" />
        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_below="@+id/textView1"
            android:text="Y"
            android:textColor="#444444"
            android:textSize="20dp" />
        <TextView
            android:id="@+id/textView3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_below="@+id/textView2"
            android:text="Angle"
            android:textColor="#444444"
            android:textSize="20dp" />
        <TextView
            android:id="@+id/textView4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_below="@+id/textView3"
            android:text="Distance"
            android:textColor="#444444"
            android:textSize="20dp" />
        <TextView
            android:id="@+id/textView5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_below="@+id/textView3"
            android:text="Direction"
            android:textColor="#444444"
            android:textSize="20dp" />
    </LinearLayout>
    <RelativeLayout
        android:id="@+id/layout_joystick"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_below="@+id/linearLayout1"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="29dp"
        android:background="@drawable/image_button_bg" >
    </RelativeLayout>


</RelativeLayout>

 

<MainActivity.java>

package com.example.joysticktest2;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    RelativeLayout layout_joystick;
    ImageView image_joystick, image_border;
    TextView textView1, textView2, textView3, textView4, textView5;

    JoyStickClass js;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView1 = (TextView) findViewById(R.id.textView1);
        textView2 = (TextView) findViewById(R.id.textView2);
        textView3 = (TextView) findViewById(R.id.textView3);
        textView4 = (TextView) findViewById(R.id.textView4);
        textView5 = (TextView) findViewById(R.id.textView5);

        layout_joystick = (RelativeLayout) findViewById(R.id.layout_joystick);

        js = new JoyStickClass(getApplicationContext(), layout_joystick, R.drawable.image_button);
        js.setStickSize(150, 150);
        js.setLayoutSize(500, 500);
        js.setLayoutAlpha(150);
        js.setStickAlpha(100);
        js.setOffset(90);
        js.setMinimumDistance(50);

        layout_joystick.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View arg0, MotionEvent arg1) {
                js.drawStick(arg1);
                if (arg1.getAction() == MotionEvent.ACTION_DOWN
                        || arg1.getAction() == MotionEvent.ACTION_MOVE) {
                    textView1.setText("X : " + String.valueOf(js.getX()));
                    textView2.setText("Y : " + String.valueOf(js.getY()));
                    textView3.setText("Angle : " + String.valueOf(js.getAngle()));
                    textView4.setText("Distance : " + String.valueOf(js.getDistance()));

                    int direction = js.get8Direction();
                    if (direction == JoyStickClass.STICK_UP) {
                        textView5.setText("Direction : Up");
                    } else if (direction == JoyStickClass.STICK_UPRIGHT) {
                        textView5.setText("Direction : Up Right");
                    } else if (direction == JoyStickClass.STICK_RIGHT) {
                        textView5.setText("Direction : Right");
                    } else if (direction == JoyStickClass.STICK_DOWNRIGHT) {
                        textView5.setText("Direction : Down Right");
                    } else if (direction == JoyStickClass.STICK_DOWN) {
                        textView5.setText("Direction : Down");
                    } else if (direction == JoyStickClass.STICK_DOWNLEFT) {
                        textView5.setText("Direction : Down Left");
                    } else if (direction == JoyStickClass.STICK_LEFT) {
                        textView5.setText("Direction : Left");
                    } else if (direction == JoyStickClass.STICK_UPLEFT) {
                        textView5.setText("Direction : Up Left");
                    } else if (direction == JoyStickClass.STICK_NONE) {
                        textView5.setText("Direction : Center");
                    }
                } else if (arg1.getAction() == MotionEvent.ACTION_UP) {
                    textView1.setText("X :");
                    textView2.setText("Y :");
                    textView3.setText("Angle :");
                    textView4.setText("Distance :");
                    textView5.setText("Direction :");
                }
                return true;
            }
        });
    }

}

 

<JoyStickClass.java>

package com.example.joysticktest2;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;

public class JoyStickClass {
    public static final int STICK_NONE = 0;
    public static final int STICK_UP = 1;
    public static final int STICK_UPRIGHT = 2;
    public static final int STICK_RIGHT = 3;
    public static final int STICK_DOWNRIGHT = 4;
    public static final int STICK_DOWN = 5;
    public static final int STICK_DOWNLEFT = 6;
    public static final int STICK_LEFT = 7;
    public static final int STICK_UPLEFT = 8;

    private int STICK_ALPHA = 200;
    private int LAYOUT_ALPHA = 200;
    private int OFFSET = 0;

    private Context mContext;
    private ViewGroup mLayout;
    private LayoutParams params;
    private int stick_width, stick_height;

    private int position_x = 0, position_y = 0, min_distance = 0;
    private float distance = 0, angle = 0;

    private DrawCanvas draw;
    private Paint paint;
    private Bitmap stick;

    private boolean touch_state = false;

    public JoyStickClass (Context context, ViewGroup layout, int stick_res_id) {
        mContext = context;

        stick = BitmapFactory.decodeResource(mContext.getResources(), stick_res_id);

        stick_width = stick.getWidth();
        stick_height = stick.getHeight();

        draw = new DrawCanvas(mContext);
        paint = new Paint();
        mLayout = layout;
        params = mLayout.getLayoutParams();
    }

    public void drawStick(MotionEvent arg1) {
        position_x = (int) (arg1.getX() - (params.width / 2));
        position_y = (int) (arg1.getY() - (params.height / 2));
        distance = (float) Math.sqrt(Math.pow(position_x, 2) + Math.pow(position_y, 2));
        angle = (float) cal_angle(position_x, position_y);


        if(arg1.getAction() == MotionEvent.ACTION_DOWN) {
            if(distance <= (params.width / 2) - OFFSET) {
                draw.position(arg1.getX(), arg1.getY());
                draw();
                touch_state = true;
            }
        } else if(arg1.getAction() == MotionEvent.ACTION_MOVE && touch_state) {
            if(distance <= (params.width / 2) - OFFSET) {
                draw.position(arg1.getX(), arg1.getY());
                draw();
            } else if(distance > (params.width / 2) - OFFSET){
                float x = (float) (Math.cos(Math.toRadians(cal_angle(position_x, position_y)))
                        * ((params.width / 2) - OFFSET));
                float y = (float) (Math.sin(Math.toRadians(cal_angle(position_x, position_y)))
                        * ((params.height / 2) - OFFSET));
                x += (params.width / 2);
                y += (params.height / 2);
                draw.position(x, y);
                draw();
            } else {
                mLayout.removeView(draw);
            }
        } else if(arg1.getAction() == MotionEvent.ACTION_UP) {
            mLayout.removeView(draw);
            touch_state = false;
        }
    }

    public int[] getPosition() {
        if(distance > min_distance && touch_state) {
            return new int[] { position_x, position_y };
        }
        return new int[] { 0, 0 };
    }

    public int getX() {
        if(distance > min_distance && touch_state) {
            return position_x;
        }
        return 0;
    }

    public int getY() {
        if(distance > min_distance && touch_state) {
            return position_y;
        }
        return 0;
    }

    public float getAngle() {
        if(distance > min_distance && touch_state) {
            return angle;
        }
        return 0;
    }

    public float getDistance() {
        if(distance > min_distance && touch_state) {
            return distance;
        }
        return 0;
    }

    public void setMinimumDistance(int minDistance) {
        min_distance = minDistance;
    }

    public int getMinimumDistance() {
        return min_distance;
    }

    public int get8Direction() {
        if(distance > min_distance && touch_state) {
            if(angle >= 247.5 && angle < 292.5 ) {
                return STICK_UP;
            } else if(angle >= 292.5 && angle < 337.5 ) {
                return STICK_UPRIGHT;
            } else if(angle >= 337.5 || angle < 22.5 ) {
                return STICK_RIGHT;
            } else if(angle >= 22.5 && angle < 67.5 ) {
                return STICK_DOWNRIGHT;
            } else if(angle >= 67.5 && angle < 112.5 ) {
                return STICK_DOWN;
            } else if(angle >= 112.5 && angle < 157.5 ) {
                return STICK_DOWNLEFT;
            } else if(angle >= 157.5 && angle < 202.5 ) {
                return STICK_LEFT;
            } else if(angle >= 202.5 && angle < 247.5 ) {
                return STICK_UPLEFT;
            }
        } else if(distance <= min_distance && touch_state) {
            return STICK_NONE;
        }
        return 0;
    }

    public int get4Direction() {
        if(distance > min_distance && touch_state) {
            if(angle >= 225 && angle < 315 ) {
                return STICK_UP;
            } else if(angle >= 315 || angle < 45 ) {
                return STICK_RIGHT;
            } else if(angle >= 45 && angle < 135 ) {
                return STICK_DOWN;
            } else if(angle >= 135 && angle < 225 ) {
                return STICK_LEFT;
            }
        } else if(distance <= min_distance && touch_state) {
            return STICK_NONE;
        }
        return 0;
    }

    public void setOffset(int offset) {
        OFFSET = offset;
    }

    public int getOffset() {
        return OFFSET;
    }

    public void setStickAlpha(int alpha) {
        STICK_ALPHA = alpha;
        paint.setAlpha(alpha);
    }

    public int getStickAlpha() {
        return STICK_ALPHA;
    }

    public void setLayoutAlpha(int alpha) {
        LAYOUT_ALPHA = alpha;
        mLayout.getBackground().setAlpha(alpha);
    }

    public int getLayoutAlpha() {
        return LAYOUT_ALPHA;
    }

    public void setStickSize(int width, int height) {
        stick = Bitmap.createScaledBitmap(stick, width, height, false);
        stick_width = stick.getWidth();
        stick_height = stick.getHeight();
    }

    public void setStickWidth(int width) {
        stick = Bitmap.createScaledBitmap(stick, width, stick_height, false);
        stick_width = stick.getWidth();
    }

    public void setStickHeight(int height) {
        stick = Bitmap.createScaledBitmap(stick, stick_width, height, false);
        stick_height = stick.getHeight();
    }

    public int getStickWidth() {
        return stick_width;
    }

    public int getStickHeight() {
        return stick_height;
    }

    public void setLayoutSize(int width, int height) {
        params.width = width;
        params.height = height;
    }

    public int getLayoutWidth() {
        return params.width;
    }

    public int getLayoutHeight() {
        return params.height;
    }

    private double cal_angle(float x, float y) {
        if(x >= 0 && y >= 0)
            return Math.toDegrees(Math.atan(y / x));
        else if(x < 0 && y >= 0)
            return Math.toDegrees(Math.atan(y / x)) + 180;
        else if(x < 0 && y < 0)
            return Math.toDegrees(Math.atan(y / x)) + 180;
        else if(x >= 0 && y < 0)
            return Math.toDegrees(Math.atan(y / x)) + 360;
        return 0;
    }

    private void draw() {
        try {
            mLayout.removeView(draw);
        } catch (Exception e) { }
        mLayout.addView(draw);
    }

    private class DrawCanvas extends View {
        float x, y;

        private DrawCanvas(Context mContext) {
            super(mContext);
        }

        public void onDraw(Canvas canvas) {
            canvas.drawBitmap(stick, x, y, paint);
        }

        private void position(float pos_x, float pos_y) {
            x = pos_x - (stick_width / 2);
            y = pos_y - (stick_height / 2);
        }
    }
}

-ReclyerView

 

버튼 누르면 추가됨
꾹 누르면 삭제되고 그냥 누르면 밑에 숫자 뜸

 

 

 

<MainActivity.java>

package com.example.recycleex;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity implements MyRecyclerAdapter.MyRecyclerViewClickListener {
    private String[] catName;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        RecyclerView recyclerView = findViewById(R.id.recyclerView);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);

        int[] cats= new int[]{
                R.drawable.cat01, R.drawable.cat02, R.drawable.cat03, R.drawable.cat04, R.drawable.cat05,
                R.drawable.cat06, R.drawable.cat07, R.drawable.cat08, R.drawable.cat09, R.drawable.cat10,
                R.drawable.cat11, R.drawable.cat12, R.drawable.cat13, R.drawable.cat14, R.drawable.cat15,
                R.drawable.cat16, R.drawable.cat17, R.drawable.cat18, R.drawable.cat19, R.drawable.cat20,
                R.drawable.cat21, R.drawable.cat22, R.drawable.cat23, R.drawable.cat24, R.drawable.cat25,

        };

        catName = new String[]{
                "R.drawable.cat01", "R.drawable.cat02", "R.drawable.cat03", "R.drawable.cat04", "R.drawable.cat05",
                "R.drawable.cat06", "R.drawable.cat07", "R.drawable.cat08", "R.drawable.cat09", "R.drawable.cat10",
                "R.drawable.cat11", "R.drawable.cat12", "R.drawable.cat13", "R.drawable.cat14", "R.drawable.cat15",
                "R.drawable.cat16", "R.drawable.cat17", "R.drawable.cat18", "R.drawable.cat19", "R.drawable.cat20",
                "R.drawable.cat21", "R.drawable.cat22", "R.drawable.cat23", "R.drawable.cat24", "R.drawable.cat25",
        };

        ArrayList<ItemData> dataList = new ArrayList<>();

        MyRecyclerAdapter adapter = new MyRecyclerAdapter(dataList);
        recyclerView.setAdapter(adapter);

        Button btnAdd = findViewById(R.id.btnAdd);
        btnAdd.setOnClickListener(new View.OnClickListener() {
            int i=0;
            @Override
            public void onClick(View v) {
                dataList.add(new ItemData(cats[i],"고양이 "+i,String.format("고양이리뷰 %03d",i)));
                adapter.notifyDataSetChanged();
                i++;
            }
        });
        adapter.setOnClickListener(this);
    }

    @Override
    public void onItemClicked(int position) {
        Toast.makeText(getApplicationContext(), ""+position, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onImageViewClicked(int position) {
        Toast.makeText(getApplicationContext(), catName[position], Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onImageLongClicked(int position) {
        Toast.makeText(getApplicationContext(),position+ " is removed",Toast.LENGTH_SHORT).show();
    }

}

<MyRecyclerAdapter.java>

package com.example.recycleex;

import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;

public class MyRecyclerAdapter extends RecyclerView.Adapter<MyRecyclerAdapter.ViewHolder> {
    ArrayList<ItemData> itemData;

    public MyRecyclerAdapter(ArrayList<ItemData> itemData) {
        this.itemData = itemData;
    }

    //Interface 생성
    public interface MyRecyclerViewClickListener{
        void onItemClicked(int position); //객체 클릭
        void onImageViewClicked(int position);
        void onImageLongClicked(int position);
    }

    private MyRecyclerViewClickListener mListener;
    public void setOnClickListener(MyRecyclerViewClickListener listener){
        this.mListener = listener;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,parent,false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) { //외부에서 가져온 데이터 셋팅
            ItemData item = itemData.get(position);
            holder.title.setText(item.getTitle());
            holder.contents.setText(item.getContents());
            holder.imageView.setImageResource(item.getImage());

            if(mListener != null){
                final int pos = position;
                holder.itemView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        mListener.onItemClicked(pos);
                    }
                });
                holder.imageView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        mListener.onImageViewClicked(pos);
                    }
                });
                holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View v) {
                        mListener.onImageLongClicked(pos);
                        Remove(pos);
                        return true;
                    }
                });
            }
    }

    @Override
    public int getItemCount() {
        return itemData.size(); //외부에서 가져온 데이터의 개수
    }

    public static class ViewHolder extends RecyclerView.ViewHolder{

        TextView title, contents;
        ImageView imageView;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            imageView= itemView.findViewById(R.id.imageView);
            imageView.setBackground(new ShapeDrawable(new OvalShape()));
            imageView.setClipToOutline(true);
            title = itemView.findViewById(R.id.textTitle);
            contents = itemView.findViewById(R.id.textContents);
        }
    }

    public void Remove(int position){
        try {
            itemData.remove(position);
            notifyDataSetChanged();
        }catch (IndexOutOfBoundsException e){
            e.printStackTrace();
        }
    }

}

<ItemData.java>

package com.example.recycleex;

public class ItemData {
    private int image;
    private String title;
    private String contents;

    public ItemData(int image, String title, String contents) {
        this.image = image;
        this.title = title;
        this.contents = contents;
    }

    public int getImage() {
        return image;
    }

    public void setImage(int image) {
        this.image = image;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContents() {
        return contents;
    }

    public void setContents(String contents) {
        this.contents = contents;
    }

}

<list_item.xml>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="wrap_content"
    android:background="@android:color/white"
    android:gravity="center_vertical"
    android:padding="8dp"
    android:layout_marginBottom="8dp">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="match_parent"
        android:gravity="center_vertical"
        android:orientation="vertical">

        <TextView
            android:id="@+id/textTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:includeFontPadding="false"
            android:textSize="18dp"
            android:textColor="@android:color/black"
            android:textStyle="bold"
            android:text="TITLE" />

        <TextView
            android:id="@+id/textContents"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:includeFontPadding="false"
            android:textSize="13dp"
            android:textColor="@android:color/darker_gray"
            android:text="CONTENTS" />
    </LinearLayout>

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:scaleType="centerCrop"
        tools:srcCompat="@tools:sample/avatars" />
</LinearLayout>

<activity_main.xml>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="#f0f0f0">

    </androidx.recyclerview.widget.RecyclerView>

    <Button
        android:id="@+id/btnAdd"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button" />
</LinearLayout>

 

<activity_main.xml>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="13dp"
        android:text="Raspberry IP Address" />

    <EditText
        android:id="@+id/ipAddress"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="textPersonName"
        android:text="192.168.0.138:21567" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/btnOn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:layout_marginRight="2dp"
            android:text="On" />

        <Button
            android:id="@+id/btnOff"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="2dp"
            android:layout_weight="1"
            android:text="Off" />


    </LinearLayout>

</LinearLayout>

 

<MainActivity>

package com.example.automicapp;

import androidx.appcompat.app.AppCompatActivity;

import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public class MainActivity extends AppCompatActivity {
    Button btnOn, btnOff;
    EditText ipAddress;
    //    Socket myAppSocket = null;
    public static String wifiModuleIP = "";
    public static int wifiModulePort = 0;
    public static String CMD = "0";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btnOn = findViewById(R.id.btnOn);
        btnOff = findViewById(R.id.btnOff);
        ipAddress = findViewById(R.id.ipAddress);

        btnOn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getIPandPort();
                CMD="O";
                Socket_AsyncTask socket_on = new Socket_AsyncTask();
                socket_on.execute();
            }
        });
        btnOff.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getIPandPort();
                CMD="F";
                Socket_AsyncTask socket_on = new Socket_AsyncTask();
                socket_on.execute();
            }
        });


    }
    public  void getIPandPort(){
        String iPandPort = ipAddress.getText().toString();
        Log.d("MY TEST","IP String: "+ iPandPort);
        String temp[] = iPandPort.split(":");
        wifiModuleIP = temp[0];
        wifiModulePort = Integer.valueOf(temp[1]);
        Log.d("MY TEST", "IP:"+wifiModuleIP);
        Log.d("MY TEST", "PORT:"+wifiModulePort);
    }

    public class Socket_AsyncTask extends AsyncTask<Void,Void,Void> {
        Socket socket;
        @Override
        protected Void doInBackground(Void... params) {
            try{
                InetAddress inetAddress = InetAddress.getByName(MainActivity.wifiModuleIP);
                socket = new java.net.Socket(inetAddress, MainActivity.wifiModulePort);
                DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
                dataOutputStream.writeBytes(CMD);
                dataOutputStream.close();
                socket.close();
            }
            catch (UnknownHostException e){e.printStackTrace();}
            catch (IOException e){e.printStackTrace();}

            return  null;
        }
    }
}

 

<AndroidManifest.xml>

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.automicapp">
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AutomicApp">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

 

 


라즈베리파이 파이썬 파일 

 

LEDControl.py

import RPi.GPIO as GPIO
import time
cur_led = 0
LED = 23

def setup():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(LED,GPIO.OUT)

def LedOn():
    GPIO.output(LED, GPIO.HIGH)
    cur_led = 1
        
def LedOff():
    GPIO.output(LED, GPIO.LOW)
    cur_led = 0

def close():
    GPIO.cleanup()

if __name__ == '__main__':
    setup()

 

pi_led_server.py

import LEDControl
from socket import *
from time import ctime
import RPi.GPIO as GPIO


LEDControl.setup()

ctrCmd = ['LedOn','LedOff']

HOST = ''
PORT = 21567
BUFSIZE = 1024
ADDR = (HOST,PORT)

tcpSerSock = socket(AF_INET, SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)

while True:
        print('Waiting for connection')
        tcpCliSock,addr = tcpSerSock.accept()
        print('...connected from :', addr)
        try:
                while True:
                    data = ''
                    data = tcpCliSock.recv(BUFSIZE)
                    data = data.decode('utf-8')
                    print(data)
                    if not data:
                        break
                    if data == ctrCmd[0]:
                        LEDControl.LedOn()
                        print('LED On: ',LEDControl.cur_led)
                    if data == ctrCmd[1]:
                        LEDControl.LedOff()
                        print('LED Off: ',LEDControl.cur_led)
        except KeyboardInterrupt:
                GPIO.cleanup()
tcpSerSock.close();

- 회전하면 reset되는 데이터 유지하는 방법 

<MainActivity.java>

package com.example.cycleex;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    public static final String PLAY_LEVEL = "playLevel";
    public static final String PLAY_SCORE = "playScore";
    TextView textLevel, textScore;
    Button btnLevelup, btnScoreup;
    int mLevel=0 , mScore=0;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textLevel = findViewById(R.id.textLevel);
        textScore = findViewById(R.id.textScore);
        btnLevelup = findViewById(R.id.btnLevelup);
        btnLevelup.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mLevel++;
                textLevel.setText("레벨: "+mLevel );
            }
        });

        btnScoreup = findViewById(R.id.btnScoreup);
        btnScoreup.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mScore +=100;
                textScore.setText("점수 : " +mScore);
            }
        });

        if(savedInstanceState == null){

        }
        else{
            mLevel = savedInstanceState.getInt(PLAY_LEVEL);
            mScore = savedInstanceState.getInt(PLAY_SCORE);
            textLevel.setText("레벨: "+ mLevel);
            textScore.setText("점수: "+ mScore);
        }

    }

    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        outState.putInt(PLAY_LEVEL, mLevel);
        outState.putInt(PLAY_SCORE, mScore);
        super.onSaveInstanceState(outState);
    }
}

<activity_main.xml>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/textLevel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="15dp"
        android:text="레벨 : 0" />

    <Button
        android:id="@+id/btnLevelup"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="레벨업" />

    <TextView
        android:id="@+id/textScore"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="15dp"
        android:text="점수 : 0" />

    <Button
        android:id="@+id/btnScoreup"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="점수증가" />
</LinearLayout>

- 회전하면 reset되는 데이터 유지하는 방법 

<MainActivity.java>

package com.example.cycleex;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    public static final String PLAY_LEVEL = "playLevel";
    public static final String PLAY_SCORE = "playScore";
    TextView textLevel, textScore;
    Button btnLevelup, btnScoreup;
    int mLevel=0 , mScore=0;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textLevel = findViewById(R.id.textLevel);
        textScore = findViewById(R.id.textScore);
        btnLevelup = findViewById(R.id.btnLevelup);
        btnLevelup.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mLevel++;
                textLevel.setText("레벨: "+mLevel );
            }
        });

        btnScoreup = findViewById(R.id.btnScoreup);
        btnScoreup.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mScore +=100;
                textScore.setText("점수 : " +mScore);
            }
        });

        if(savedInstanceState == null){

        }
        else{
            mLevel = savedInstanceState.getInt(PLAY_LEVEL);
            mScore = savedInstanceState.getInt(PLAY_SCORE);
            textLevel.setText("레벨: "+ mLevel);
            textScore.setText("점수: "+ mScore);
        }

    }

    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        outState.putInt(PLAY_LEVEL, mLevel);
        outState.putInt(PLAY_SCORE, mScore);
        super.onSaveInstanceState(outState);
    }
}

<activity_main.xml>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/textLevel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="15dp"
        android:text="레벨 : 0" />

    <Button
        android:id="@+id/btnLevelup"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="레벨업" />

    <TextView
        android:id="@+id/textScore"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="15dp"
        android:text="점수 : 0" />

    <Button
        android:id="@+id/btnScoreup"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="점수증가" />
</LinearLayout>

- 글 적고 저장 누르면 다시 실행시켰을 때 저장되어 있음 .

 

<MainaActivity.java>

package com.example.shared_p_app;

import androidx.appcompat.app.AppCompatActivity;

import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends AppCompatActivity {

    private SharedPreferences preferences;
    private SharedPreferences.Editor editor;
    private int SelectedColor;
    EditText editText;
    Button btnRed, btnGreen, btnBlue;
    Button btnSave, btnRemove;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editText = findViewById(R.id.editText);
        btnRed = findViewById(R.id.btnRed);
        btnGreen = findViewById(R.id.btnGreen);
        btnBlue = findViewById(R.id.btnBlue);
        btnSave = findViewById(R.id.btnSave);
        btnRemove = findViewById(R.id.btnRemove);

        setBtnColorListener();
        setBtnPreferenceListener();

        preferences = PreferenceManager.getDefaultSharedPreferences(this);
        editor = preferences.edit();

        initializeValue();
    }

    public void setBtnColorListener() {
        View.OnClickListener listener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switch (v.getId()){
                    case R.id.btnRed:
                        SelectedColor = Color.RED;
                        editText.setTextColor(Color.RED);
                        break;
                    case R.id.btnGreen:
                        SelectedColor = Color.GREEN;
                        editText.setTextColor(Color.GREEN);
                        break;
                    case R.id.btnBlue:
                        SelectedColor = Color.BLUE;
                        editText.setTextColor(Color.BLUE);
                        break;
                }
            }
        };
        btnRed.setOnClickListener(listener);
        btnGreen.setOnClickListener(listener);
        btnBlue.setOnClickListener(listener);

    }

    public void initializeValue() {
        editText.setText(preferences.getString("text", "저장된 데이터가 없음"));
        editText.setTextColor(preferences.getInt("color", Color.GREEN));
    }

    public void setBtnPreferenceListener() {
        View.OnClickListener listener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switch (v.getId()){
                    //데이터 저장하기
                    case R.id.btnSave:
                        editor.putInt("color", SelectedColor);
                        editor.putString("text",editText.getText().toString());
                        editor.apply();
                        break;
                    // 데이터 제거하기
                    case R.id.btnRemove:
                        editor.remove("color");
                        editor.remove("text");
                        editor.apply();
                        break;
                }
            }
        };
        btnSave.setOnClickListener(listener);
        btnRemove.setOnClickListener(listener);

    }

}

<activity_main.xml>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/btnSave"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="2dp"
            android:layout_weight="1"
            android:text="저장" />

        <Button
            android:id="@+id/btnRemove"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="2dp"
            android:layout_weight="1"
            android:text="제거" />
    </LinearLayout>

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="textPersonName"
        android:hint="텍스트를 입력하세요" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/btnRed"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="2dp"
            android:layout_weight="1"
            android:text="RED" />

        <Button
            android:id="@+id/btnGreen"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="2dp"
            android:layout_marginRight="2dp"
            android:layout_weight="1"
            android:text="GREEN" />

        <Button
            android:id="@+id/btnBlue"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:layout_marginLeft="2dp"
            android:text="Button" />
    </LinearLayout>
</LinearLayout>

-이메일 저장 누르고 로그인 하면 이메일 저장되게 하기 

<activity_main.xml>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <EditText
        android:id="@+id/editEmail"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="textPersonName"
        android:hint="이메일을 입력하세요" />

    <EditText
        android:id="@+id/editPassword"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="textPersonName"
        android:hint="패스워드를 입력하세요" />

    <CheckBox
        android:id="@+id/checkSave"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="이메일저장" />

    <Button
        android:id="@+id/btnLogin"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="로그인" />
</LinearLayout>

 

<MainActivity>

package com.example.loginexapp;

import androidx.appcompat.app.AppCompatActivity;

import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.widget.CheckBox;
import android.widget.EditText;

public class MainActivity extends AppCompatActivity {
    private EditText editEmail, editPassword;
    private CheckBox checkSave;

    SharedPreferences preferences;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        preferences = PreferenceManager.getDefaultSharedPreferences(this);
        editEmail = findViewById(R.id.editEmail);
        editPassword = findViewById(R.id.editPassword);
        checkSave= findViewById(R.id.checkSave);

        Boolean isChecked = preferences.getBoolean("save", false);
        checkSave.setChecked(isChecked);
        if (isChecked){
            String email = preferences.getString("email", "");
            editEmail.setText(email);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        SharedPreferences.Editor editor = preferences.edit();

        editor.putBoolean("save", checkSave.isChecked());
        editor.putString("email", editEmail.getText().toString());

        editor.apply();
    }
}

 

1. 조립 

 

2.  -전체 회로구성(라즈베리파이 + L293D + 모터)

 

- L293D 회로 구성 (둥근 홈이 오른쪽에 위치해 있음 / 홈의 방향을 반드시 확인)

- 라즈베리파이 + L293D

 

- 초음파 센서로 거리측정 구현하기

import RPi.GPIO as GPIO
import time
 
GPIO.setmode(GPIO.BCM)
 
TRIG = 23
ECHO = 24
 
GPIO.setup(TRIG, GPIO.OUT)
GPIO.setup(ECHO, GPIO.IN)
 
def getDistance():
    GPIO.output(TRIG, False)
    time.sleep(1)
 
    GPIO.output(TRIG, True)
    time.sleep(0.00001)
    GPIO.output(TRIG,False)
 
    while GPIO.input(ECHO)==0:
        pulse_start = time.time()
    while GPIO.input(ECHO)==1:
        pulse_end = time.time()
 
    pulse_duration = pulse_end - pulse_start
 
    distance = pulse_duration * 17150
    distance = round(distance,2)
 
    return distance  
 
if __name__ == '__main__':
    try: 
        while True:
            distance_value = getDistance()
            if distance_value > 2 and distance_value < 400:
                print("Distance is {:.2f} cm".format(distance_value))
            else:
                print("Out of range")
    except KeyboardInterrupt:
        print("Terminated by Keborad Interrupt")
        GPIO.cleanup()

 

- 모터를 5초 동안 전진/우회전/좌회전/정지 동작 시키는 코드 구현

#import GPIO library / time library
import RPi.GPIO as GPIO
import time
 
GPIO.setmode(GPIO.BCM)
 
RIGHT_FORWARD = 26
RIGHT_BACKWARD = 19
RIGHT_PWM = 13
LEFT_FORWARD = 16
LEFT_BACKWARD = 20
LEFT_PWM = 21
 
GPIO.setup(RIGHT_FORWARD,GPIO.OUT)
GPIO.setup(RIGHT_BACKWARD,GPIO.OUT)
GPIO.setup(RIGHT_PWM,GPIO.OUT)
GPIO.output(RIGHT_PWM,0)
RIGHT_MOTOR = GPIO.PWM(RIGHT_PWM,100)
RIGHT_MOTOR.start(0)
RIGHT_MOTOR.ChangeDutyCycle(0)
 
GPIO.setup(LEFT_FORWARD,GPIO.OUT)
GPIO.setup(LEFT_BACKWARD,GPIO.OUT)
GPIO.setup(LEFT_PWM,GPIO.OUT)
GPIO.output(LEFT_PWM,0)
LEFT_MOTOR = GPIO.PWM(LEFT_PWM,100)
LEFT_MOTOR.start(0)
LEFT_MOTOR.ChangeDutyCycle(0)
 
#RIGHT Motor control
def rightMotor(forward, backward, pwm):
    GPIO.output(RIGHT_FORWARD,forward)
    GPIO.output(RIGHT_BACKWARD,backward)
    RIGHT_MOTOR.ChangeDutyCycle(pwm)
 
#Left Motor control
def leftMotor(forward, backward, pwm):
    GPIO.output(LEFT_FORWARD,forward)
    GPIO.output(LEFT_BACKWARD,backward)
    LEFT_MOTOR.ChangeDutyCycle(pwm)
 
if __name__ == '__main__':
    try: 
        while True:
            #5초 전진 
            rightMotor(1 ,0, 70)
            leftMotor(1 ,0, 70)
            time.sleep(5)
            #5초 우회전 
            rightMotor(1 ,0, 70)
            leftMotor(0 ,0, 0)
            time.sleep(5)
            #5초 좌회전 
            rightMotor(0 ,0, 0)
            leftMotor(1 ,0, 70)
            time.sleep(5)
            #5초 정지 
            rightMotor(0 ,0, 0)
            leftMotor(0 ,0, 0)
            time.sleep(5)            
    except KeyboardInterrupt:
        print("Terminated by Keborad Interrupt")
        GPIO.cleanup()

 

- 자율 주행 코드 구현하기 

 

-초음파센서 3개 달았음 

import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)

TRIG = 23
ECHO = 24

GPIO.setup(TRIG, GPIO.OUT)
GPIO.setup(ECHO, GPIO.IN)

TRIG_R = 27
ECHO_R = 17

GPIO.setup(TRIG_R, GPIO.OUT)
GPIO.setup(ECHO_R, GPIO.IN)

TRIG_L = 18
ECHO_L = 25

GPIO.setup(TRIG_L, GPIO.OUT)
GPIO.setup(ECHO_L, GPIO.IN)

RIGHT_FORWARD = 16
RIGHT_BACKWARD = 20
RIGHT_PWM = 21
LEFT_FORWARD = 19
LEFT_BACKWARD = 26
LEFT_PWM = 13

GPIO.setup(RIGHT_FORWARD,GPIO.OUT)
GPIO.setup(RIGHT_BACKWARD,GPIO.OUT)
GPIO.setup(RIGHT_PWM,GPIO.OUT)
GPIO.output(RIGHT_PWM,0)
RIGHT_MOTOR = GPIO.PWM(RIGHT_PWM,100)
RIGHT_MOTOR.start(0)
RIGHT_MOTOR.ChangeDutyCycle(0)

GPIO.setup(LEFT_FORWARD,GPIO.OUT)
GPIO.setup(LEFT_BACKWARD,GPIO.OUT)
GPIO.setup(LEFT_PWM,GPIO.OUT)
GPIO.output(LEFT_PWM,0)
LEFT_MOTOR = GPIO.PWM(LEFT_PWM,100)
LEFT_MOTOR.start(0)
LEFT_MOTOR.ChangeDutyCycle(0)

def getDistance():
    GPIO.output(TRIG,GPIO.LOW)
    time.sleep(1)

    GPIO.output(TRIG,GPIO.HIGH)
    time.sleep(0.00001)
    GPIO.output(TRIG,GPIO.LOW)

    while GPIO.input(ECHO)==0:
        pulse_start = time.time()
    
    while GPIO.input(ECHO)==1:
        pulse_end = time.time()

    pulse_duration = pulse_end - pulse_start
    distance = pulse_duration * 17150
    distance = round(distance,2)
    return distance

def getDistanceRight():
    GPIO.output(TRIG_R,GPIO.LOW)
    time.sleep(1)

    GPIO.output(TRIG_R,GPIO.HIGH)
    time.sleep(0.00001)
    GPIO.output(TRIG_R,GPIO.LOW)

    while GPIO.input(ECHO_R)==0:
        pulse_start = time.time()
    
    while GPIO.input(ECHO_R)==1:
        pulse_end = time.time()

    pulse_duration = pulse_end - pulse_start
    distance = pulse_duration * 17150
    distance = round(distance,2)
    return distance
# 
def getDistanceLeft():
    GPIO.output(TRIG_L,GPIO.LOW)
    time.sleep(1)

    GPIO.output(TRIG_L,GPIO.HIGH)
    time.sleep(0.00001)
    GPIO.output(TRIG_L,GPIO.LOW)

    while GPIO.input(ECHO_L)==0:
        pulse_start = time.time()
    
    while GPIO.input(ECHO_L)==1:
        pulse_end = time.time()

    pulse_duration = pulse_end - pulse_start
    distance = pulse_duration * 17150
    distance = round(distance,2)
    return distance

#RIGHT Motor control
def rightMotor(forward, backward, pwm):
    GPIO.output(RIGHT_FORWARD,forward)
    GPIO.output(RIGHT_BACKWARD,backward)
    RIGHT_MOTOR.ChangeDutyCycle(pwm)

#Left Motor control
def leftMotor(forward, backward, pwm):
    GPIO.output(LEFT_FORWARD,forward)
    GPIO.output(LEFT_BACKWARD,backward)
    LEFT_MOTOR.ChangeDutyCycle(pwm)

if __name__ == '__main__':
    try: 
        while True:
            distance_value = getDistance()
            distance_value2 = getDistanceRight()
            distance_value3 = getDistanceLeft()
            # 50cm 이상 거리인지 모니터링
            if distance_value > 60 and distance_value2 > 60 and distance_value > 60:
                #1초간 전진    
                print("Forward " + str(distance_value))
                print("Right " + str(distance_value2))
                print("Left " + str(distance_value3))
                rightMotor(1 ,0, 60)
                leftMotor(1 ,0, 60)            
                time.sleep(0.2)
            else:
                #후진 먼저 0.5초 하고나서 밑에 if or else 실행됨 
                rightMotor(0 ,1, 60)
                leftMotor(0 ,1, 60)            
                time.sleep(0.5)
                if distance_value3 > distance_value2:
                    # 1초간 왼쪽으로 회전 -
                    print("Turn Left " + str(distance_value))
                    rightMotor(0 ,0, 0)            
                    leftMotor(1 ,0, 60)            
                    time.sleep(0.2)
                else:
                    print("Turn Right " + str(distance_value))
                    rightMotor(1 ,0, 0)            
                    leftMotor(0 ,0, 60)            
                    time.sleep(0.2)
    except KeyboardInterrupt:
        print("Terminated by Keborad Interrupt")
        GPIO.cleanup()

+ Recent posts