1. 程式人生 > >簡單java(Android)pi4j和Socke實現respberry 3B上GPIO的LED燈控制

簡單java(Android)pi4j和Socke實現respberry 3B上GPIO的LED燈控制

首先下載http://get.pi4j.com/download/pi4j-1.2-SNAPSHOT.zip(使用SNAPSHOT是因為3B要用這個新版本才正常,1.1版本不能在3B上執行),解的jar檔案使用eclipse進行開發,把3B作為伺服器進行socket埠監聽,沒有實現多執行緒多客戶端監聽,簡單的點對點監聽。
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import com.pi4j.io.gpio.*;
//Raspberry Server ,accept action 1/0
public class Rasp {

	public static final GpioController gpio=GpioFactory.getInstance();
	
	public static void main(String[] args) {
		ServerSocket server = null;
		Socket you = null;
		DataOutputStream out = null;
		DataInputStream in = null;
		GpioPinDigitalOutput led=gpio.provisionDigitalOutputPin(RaspiPin.GPIO_29, "",PinState.LOW);
		try {
			server = new ServerSocket(8970);
		} catch (Exception e) {
			e.printStackTrace();
		}
		try {
			System.out.println("Wait.....");
			you = server.accept();
			in = new DataInputStream(you.getInputStream());
			out = new DataOutputStream(you.getOutputStream());
			while (true) {
				int i = in.readInt();
				System.out.println(i);
				// GPIO Control
				if (i == 1) {
					led.high();
					out.writeUTF("LED ON");
				} else if (i == 0) {
					led.low();
					out.writeUTF("LED OFF");
				} else
					out.writeUTF("Invalid");
				Thread.sleep(500);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

編譯好的class檔案上傳到3B上,3B上也需要安裝pi4j(這部分網上另有教程)。使用shell命令執行(需要帶類的路徑,不然不能執行)

java -classpath .:classes:/opt/pi4j/lib/'*' Rasp

下面是pc端的程式碼實現,只有簡單的介面,兩個按鈕。

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

//電腦作為控制端
//實現開關介面按鈕控制
class ledBut extends JFrame implements ActionListener {
	JPanel pl;
	JButton on, off;
	Socket socket = null;
	DataInputStream in = null;
	DataOutputStream out = null;
	String re = null;

	public ledBut() {
		pl = new JPanel();
		on = new JButton("開");
		off = new JButton("關");
		on.addActionListener(this);
		off.addActionListener(this);
		this.setTitle("Raspberry LED Control");
		this.setBounds(400, 300,320,80);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setVisible(true);

		pl.setLayout(new FlowLayout());
		pl.add(on);
		pl.add(off);
		this.add(pl);
		
		try {
			socket = new Socket("192.168.12.107", 8970);//改成自己的3B的ip
			in = new DataInputStream(socket.getInputStream());
			out = new DataOutputStream(socket.getOutputStream());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void actionPerformed(ActionEvent arg0) {
		try {
			if (arg0.getSource() == on) {
				out.writeInt(1);
				on.setEnabled(false);
				off.setEnabled(true);
			} else if (arg0.getSource() == off) {
				out.writeInt(0);
				on.setEnabled(true);
				off.setEnabled(false);
			}
			else
				System.out.println("操作無效");
			re = in.readUTF();
			System.out.println(re);
			Thread.sleep(100);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

public class pc {

	public static void main(String[] args) {
		new ledBut();
//舊版控制檯操作
//		Socket socket = null;
//		DataInputStream in = null;
//		DataOutputStream out = null;
//		String re = null;

//		Scanner read = null;
//		try {
//			socket = new Socket("192.168.12.107", 8970);
//			in = new DataInputStream(socket.getInputStream());
//			out = new DataOutputStream(socket.getOutputStream());
//			read = new Scanner(System.in);
//			while (true) {
//			int i = read.nextInt();
//			out.writeInt(i);
//			re = in.readUTF();
//			System.out.println(re);
//			Thread.sleep(500);
//			}
//		} catch (Exception e) {
//			e.printStackTrace();
//		} finally {
//			if (read != null)
//			 read.close();
//		}
	}

}


Android端的類似(IDEA上開發),也只是簡單的兩個按鈕。activity如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
    <Button android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/on_button"
            android:text="開"/>
    <Button android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/off_button"
            android:text="關"/>
</LinearLayout>
實現的程式碼
package io.hyz.netled;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

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

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    Socket ledSocket = null;
    DataOutputStream dataOutputStream = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button on = (Button) findViewById(R.id.on_button);
        Button off = (Button) findViewById(R.id.off_button);
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    ledSocket = new Socket("192.168.12.34", 8970);
                    dataOutputStream = new DataOutputStream(ledSocket.getOutputStream());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        on.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (ledSocket != null) {
                    new LEDThread(1).start();
                }
            }
        });
        off.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (ledSocket != null) {
                    new LEDThread(0).start();
                }
            }
        });
    }

    class LEDThread extends Thread {
        int status;

        public LEDThread(int status) {
            this.status = status;
        }

        @Override
        public void run() {
            Log.d(TAG, "run: " + Thread.currentThread().getId());
            try {
                dataOutputStream.writeInt(status);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (dataOutputStream != null) {
            try {
                dataOutputStream.close();
                dataOutputStream = null;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

實現的功能很簡單,只是開和關,這只是自己簡單記錄下的,兩個客戶端都沒有狀態返回,可能後面實現