天天看点

Android串口编程--开关灯Demo(附源码)

1、项目简述

第二次玩硬件了,第一次是通过局域网控制门的开关,这次是通过ZB(大概就是这么叫,具体名字不清楚)控制灯的开关,感觉控制硬件也就是给硬件发个byte数组而已。

这里有个框架usb-serial-for-android 可以直接使用,但是里面并没有教你怎么写数据,我还是一个一个类里面找write相关方法,后来终于找到了是通过UsbSerialPort类下的write(final byte[] src, final int timeoutMillis)方法实现数据的发送的。

2、实现后的感想

这个demo感觉挺难测试的,而且一旦发现问题,很难找到问题所在。 

测试难在于,电脑上的模拟器是没法测试的(反正我的模拟器是测试失败的),因为模拟器访问不到电脑的USB接口,在手机上也是很难测试,因为手机是没法给外部接口供电的,除非你有这样一根带供电功能的OTG线。 

所以我们测试对象就是一些安卓设备,比如说Android电视之类的。

3、操作步骤

(1)当你在初始界面获得到串口信息时 

(2)点击一个串口,可以进入到另一个Activity里去 

(3)在这里你就可以通过UsbSerialPort的write进行写数据了。 

说的是这么简单,但是实际上第一次接触的猿友应该是会感到很迷茫的。

4、主要代码

    public void writeData(String data) {

        if(mSerialPort == null) return;

        try {

            //这里需要对数据做一次处理,可能是因为接收方(台灯)那边需要对数据解析,不一定每个接收方都需要处理,PS:我在这里就踩了个坑了

            byte[] bytes = StringToBytes.getFCSData(data.getBytes()); 

            int result = mSerialPort.write(bytes, 1000);

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

1

2

3

4

5

6

7

8

9

10

这个就是我写数据时的代码,通过UsbSerialPort进行写数据,但是我写之前,先对传进来的字符串进行处理,不处理的话,发送到灯上的数据是没有用的,发送成功了,灯也不会亮。在此,我可是踩到了个大坑的。

因为这个demo要集成到项目中去,所以我把代码整理了一下,只需要在初始化一下,然后调用WriteData方法,即可发送数据了(前提是你得访问到了串口),具体代码如下:

public class DeviceManager {

    private static final int MESSAGE_REFRESH = 101;

    private static final long REFRESH_TIMEOUT_MILLIS = 5000;

    private List<UsbSerialPort> mPortList = new ArrayList<>();

    private UsbManager mUsbManager;

    private UsbSerialPort mSerialPort;

    private SerialInputOutputManager mSerialIoManager;

    private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();

    public Context mContext;

    public DeviceManager(Context context) {

        mUsbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);

        mContext = context;

    }

    private final Handler mHandler = new Handler() {

        @Override

        public void handleMessage(Message msg) {

            switch (msg.what) {

                case MESSAGE_REFRESH:

                    refreshDeviceList();

                    mHandler.sendEmptyMessageDelayed(MESSAGE_REFRESH, REFRESH_TIMEOUT_MILLIS);

                    break;

                default:

                    super.handleMessage(msg);

                    break;

            }

        }

    };

    public void resume() {

        mHandler.sendEmptyMessage(MESSAGE_REFRESH);

    }

    public void pause() {

        mHandler.removeMessages(MESSAGE_REFRESH);

    }

    private void refreshDeviceList() {

        new AsyncTask<Void, Void, List<UsbSerialPort>>() {

            @Override

            protected List<UsbSerialPort> doInBackground(Void... params) {

                SystemClock.sleep(1000);

                final List<UsbSerialDriver> drivers =

                        UsbSerialProber.getDefaultProber().findAllDrivers(mUsbManager);

                final List<UsbSerialPort> result = new ArrayList<UsbSerialPort>();

                for (final UsbSerialDriver driver : drivers) {

                    final List<UsbSerialPort> ports = driver.getPorts();

                    result.addAll(ports);

                }

                return result;

            }

            @Override

            protected void onPostExecute(List<UsbSerialPort> result) {

                mPortList.clear();

                mPortList.addAll(result);

                if (!result.isEmpty()) {

                    mSerialPort = mPortList.get(0);

                    //获取到一次即可,随后删除消息

                    mHandler.removeMessages(MESSAGE_REFRESH);

                    initPort();

                }

            }

        }.execute((Void) null);

    }

    private void initPort() {

        UsbDeviceConnection connection = mUsbManager.openDevice(mSerialPort.getDriver().getDevice());

        if (connection == null) {

            return;

        }

        try {

            mSerialPort.open(connection);

            //默认参数

            //sPort.setParameters(115200, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);

            //串口调试参数

            mSerialPort.setParameters(38400, 8, UsbSerialPort.STOPBITS_1, UsbSerialPort.PARITY_NONE);

        } catch (IOException e) {

            try {

                mSerialPort.close();

            } catch (IOException e2) {

                // Ignore.

            }

            mSerialPort = null;

            return;

        }

        onDeviceStateChange();

    }

    public void writeData(String data) {

        if(mSerialPort == null) return;

        try {

            byte[] bytes = StringToBytes.getFCSData(data.getBytes());

            int result = mSerialPort.write(bytes, 1000);

            Toast.makeText(mContext, data + ":" + result, Toast.LENGTH_SHORT).show();

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

    private void stopIoManager() {

        if (mSerialIoManager != null) {

            mSerialIoManager.stop();

            mSerialIoManager = null;

        }

    }

    private void startIoManager() {

        if (mSerialPort != null) {

            mSerialIoManager = new SerialInputOutputManager(mSerialPort, mListener);

            mExecutor.submit(mSerialIoManager);

        }

    }

    private void onDeviceStateChange() {

        stopIoManager();

        startIoManager();

    }

    private final SerialInputOutputManager.Listener mListener =

            new SerialInputOutputManager.Listener() {

                @Override

                public void onRunError(Exception e) {

                }

                @Override

                public void onNewData(final byte[] data) {

                }

            };

}

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

136

137

138

139

140

141

142

在我的Activity中是这样写的,就是这样了。

public class MainActivity extends Activity {

    DeviceManager mManager;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        mManager = new DeviceManager(this);

        findViewById(R.id.LightOn).setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                mManager.writeData("LightOn");

            }

        });

    }

    @Override

    protected void onResume() {

        super.onResume();

        mManager.resume();

    }

    @Override

    protected void onPause() {

        super.onPause();

        mManager.pause();

    }

}

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

注:建议第一次接触的人,还是先去看看usb-serial-for-android 这个框架,能获取到串口设备后,再来看看我写的方法。

5、Demo下载

【点击下载】

原文:https://blog.csdn.net/chang_1134/article/details/68062212