Android下的串口通信实战之电子秤交互

本文为博主原创文章,未经博主允许不得转载。如有问题,请与我联系( QQ:3290985311)朱小姐。

本篇实战是在Android下的串口通信实战之控制客显的基础上修改的。

上一篇的实战demo只用了Android设备向硬件发送指令。但是串口通信是双向通信,所以这篇实战讲的是双向通信交互。本篇的例子直接使用上一篇的例子继续。


1、硬件设备

Android平板,电子秤

Android下的串口通信实战之电子秤交互_第1张图片

2、通信过程

a、设置波特率和串口地址---demo里用的波特率是9600,串口地址是"/dev/ttyS3" 

b、打开串口

private SerialPort mSerialPort = null;
String path = "/dev/ttyS3";
int baudrate = 9600;
private FileDescriptor mFd;
private FileInputStream mFileInputStream;
private FileOutputStream mFileOutputStream;
mSerialPort = new SerialPort(new File(path), baudrate, 0);
public SerialPort(File device, int baudrate, int flags) throws SecurityException, IOException {

		/* Check access permission */
		if (!device.canRead() || !device.canWrite()) {
			try {
				/* Missing read/write permission, trying to chmod the file */
				Process su;
				su = Runtime.getRuntime().exec("/system/bin/su");
				String cmd = "chmod 666 " + device.getAbsolutePath() + "\n"
						+ "exit\n";
				su.getOutputStream().write(cmd.getBytes());
				if ((su.waitFor() != 0) || !device.canRead()
						|| !device.canWrite()) {
					throw new SecurityException();
				}
			} catch (Exception e) {
				e.printStackTrace();
				throw new SecurityException();
			}
		}

		mFd = open(device.getAbsolutePath(), baudrate, flags);
		if (mFd == null) {
			Log.e(TAG, "native open returns null");
			throw new IOException();
		}
		mFileInputStream = new FileInputStream(mFd);
		mFileOutputStream = new FileOutputStream(mFd);
	}
注意上面代码,打开串口地址时,已经获取了输入流和输出流。mFileInputStream用来读取硬件返回的数据,mFileOutputStream用来向硬件发送指令数据。

串口通信有一个特点,外设会不停地返回数据,也没有停止的标志或指令。所以开一个读线程去读取串口返回数据,并用接口返回byte数据。

private class ReadThread extends Thread {

		@Override
		public void run() {
			super.run();
			while(!isInterrupted()) {
				int size;
				try {
					byte[] buffer = new byte[512];
					if (mInputStream == null) return;
					size = mInputStream.read(buffer);
					if (size > 0) {
						onDataReceived(buffer, size);//返回数据的接口
					}
					try
					{
						Thread.sleep(50);
					} catch (InterruptedException e)
					{
						e.printStackTrace();
					}
				} catch (IOException e) {
					e.printStackTrace();
					return;
				}
			}
		}
	}
接口的定义

protected abstract void onDataReceived(final byte[] buffer, final int size);
在需要处理串口数据的界面实现接口方法

@Override
	protected void onDataReceived(byte[] buffer, int size) {
		// TODO Auto-generated method stub
		String result = new String(buffer,0,size);
		if(result.length()>0){
			String data = "";
			Matcher matcher = Pattern.compile("[0-9]\\d{3}").matcher(result);
			if(matcher.find()){
				data = matcher.group();
			}
			//最终拿到符合条件的data
		}

		Log.d("zhu", "onDataReceived="+result);
	}
因为本例中使用的电子秤是大华的。大华电子秤直接返回重量数据,例如电子秤上显示的是0.255kg,返回的数据就是0255,因为会不停得向串口发送数据,所以接收的数据有可能是0255 0255 0255等,所以使用正则表达式直接拿到4位数字,注意数据与数据之间还有可能有换行。所以使用正则会比使用split更精确。

注意:不同的设备,返回的数据不一样。要具体情况具体处理数据


上一篇讲的就是使用串口发送数据,以上讲的是接收串口数据。其实对于串口通信,发送数据和接收数据的过程是一样的。不同的是,发送的指令和接收的指令会根据不同的设备而有所不同。

附上上一篇的串口发送数据代码

private class SendingThread extends Thread {
		private SendingThread() {
		}

		public void run() {
			while (true) {
				if (isInterrupted())
					return;
				try {
					if (mOutputStream != null)
					mOutputStream.write(mBuffer);//关键代码
				} catch (IOException localIOException) {
					localIOException.printStackTrace();
				}
			}
		}
	}
不开线程的话,就不需要这么处理了,直接一句话搞定

public void SendStr(byte[] paramArrayOfByte) {
		try {
			if (this.mOutputStream != null)
				this.mOutputStream.write(paramArrayOfByte);
			return;
		} catch (IOException localIOException) {
			localIOException.printStackTrace();
		}
	}
其中mBuffer是你要传送的数据的字节数组。

源码链接

https://download.csdn.net/download/qq_27570955/9767140 



你可能感兴趣的:(实战)