注:本文为原创文章,转载时请注明转载地址。
在上篇文章中介绍了通过串口向LED液晶显示屏发送数据的方式,同样,通过串口也可以让你的程序来捕捉外部设备(开关类设备)触发的事件或者从外部设备读取数据(传感器等)。 下面介绍一个通过脚踏开关来控制应用程序操作的例子。
脚踏开关—分为两种:一种就是日常生活中最普通的电路开关,通过电路的闭合来控制 电路的接通;另一种就是在开关中加入一个上位机,其他的都一样。
功能:当脚踏开关踩下(电路接通)时,触发你的程序中的一个动作,比如启动/停止一项任务。
接线图:
将开关的两根线分别接在串口的输入、输出(2、3号)引脚,如图:
根据脚踏开关的两种类型采用不同的方式
1.带上位机的
该方式比较简单,当开关的闭合触发事件时上位机会通过串口向pc发送数据,在程序中采用串口的事件监听模型即可进行事件的捕捉,主要代码如下:
try {
serialPort.addEventListener(new SerialPortEventListener() {
public void serialEvent(SerialPortEvent serialPortEvent) {
//在此进行事件捕捉处理
}
});
} catch (TooManyListenersException e) {
serialPort.close();
throw new SerialConnectionException("too many listeners added");
}
2.普通的开关
此种方式由于没有上位机主动向pc发送数据,所以不能再采用上述方式来进行捕获事件,解决的方式是:让一个单独的线程每隔一定的时间向串口发送数据,然后让另一个线程不停的在串口接收数据,如果能够接受到数据说明开关闭合,否则说明开关断开。
相关程序代码:
public class Demo {
static SwitchControl control;
private InputStream in;
private OutputStream os;
private SerialPort serialPort;
boolean inited = false;
boolean stoped = false;
long beg = System.currentTimeMillis();
public boolean init() {
if (inited) {
return true;
}
try {
CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier("COM1");
serialPort = (SerialPort) portId.open("SerialBean", 4000);
serialPort.setSerialPortParams(9600,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
serialPort.setDTR(true);
in = serialPort.getInputStream();
os = serialPort.getOutputStream();
inited = true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
public void writePort(int s) {
try {
os.write(s);
os.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
public void start() {
Thread send = new Thread(new SendData());
Thread recive = new Thread(new ReceiveData());
send.start();
recive.start();
}
public void close() {
stoped = true;
try {
Thread.sleep(20);
if (in != null) {
in.close();
}
if (os != null) {
os.close();
}
if (serialPort != null)
serialPort.close();
} catch (Exception e) {
e.printStackTrace();
}
}
class ReceiveData implements Runnable {
public void run() {
while (true) {
if (stoped) {
break;
}
byte[] b = new byte[10];
try {
if (in.read(b) == 0) {
continue;
}
long end = System.currentTimeMillis();
//处去噪声影响,通过连续两次接受到数据的时间差来判断是一次长时间的踩踏还是连续2次或者多次踩踏
if (end - beg > 20) {
Thread tt = new Thread(new Task());
tt.start();
}
Thread.sleep(10);
beg = System.currentTimeMillis();
} catch (Exception e) {
break;
}
}
}
}
class SendData implements Runnable {
public void run() {
while (true) {
if (stoped) {
break;
}
writePort(0);
try {
Thread.sleep(5);
} catch (Exception e) {
e.printStackTrace();
break;
}
}
}
}
class Task implements Runnable {
public void run() {
// 相关任务
System.out.println("捕捉到事件.............");
}
}
public static void main(String[] args) {
Demo demo = new Demo();
if (!demo.init()) {
System.err.println("初始化串口失败!");
return;
}
demo.start();
}
}