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

66 篇文章 0 订阅

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方法,即可发送数据了(前提是你得访问到了串口),具体代码如下:


/**
 * Created by Administrator on 2017-03-27.
 * Author jiangxiaochang
 */
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 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值