簡單java(Android)pi4j和Socke實現respberry 3B上GPIO的LED燈控制
阿新 • • 發佈:2019-02-02
首先下載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();
}
}
}
}
實現的功能很簡單,只是開和關,這只是自己簡單記錄下的,兩個客戶端都沒有狀態返回,可能後面實現