1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > java 获取温度_Java利用RXTX串口通信工具类获取DS18B20温度传感器的温度值

java 获取温度_Java利用RXTX串口通信工具类获取DS18B20温度传感器的温度值

时间:2022-03-09 13:51:50

相关推荐

java 获取温度_Java利用RXTX串口通信工具类获取DS18B20温度传感器的温度值

环境:Windows10,Eclipse4.5.2,JDK1.7

设备:DS18B20温度传感器(4线,485接口),USB转485接口转换器,笔记本电脑

注意点:RTU传输,使用的是字节,那么在程序中常会遇到传给设备的字节无法用byte表示,可能会溢出(例如校验值),所以也可以用int值传入,效果相同。

MyTwoWaySerialComm.java [核心类]

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.util.Scanner;

import mPort;

import mPortIdentifier;

import gnu.io.SerialPort;

/**

* 双向串行通信类

* @author 都颜汗

*

*/

public class MyTwoWaySerialComm {

/**

* 端口连接

* @param portName

* @throws Exception

*/

void connect(String portName) throws Exception {

// 通过端口名获取端口标志对象

CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);

// 检测当前端口是否已有所属(即检测是否被占用)

boolean isOwned = portIdentifier.isCurrentlyOwned();

// 若已经被占用

if(isOwned)

{

System.out.println("当前端口已经被占用");

}

// 若当前端口可用

else {

// 打开通信端口 (注意:这里使用应用名,和打开超时时间,单位ms),打开后获取通信端口对象

CommPort commPort = portIdentifier.open(this.getClass().getName(), 2000);

// 判断当前这个端口对象commPort是否是串行端口类的对象,注意:这里如果没有获取到commPort对象 一样会返回false

if(commPort instanceof SerialPort)

{

// 如果是串行端口(电脑上除了串行端口,还有并行端口),则转换成串行端口对象

SerialPort serialPort = (SerialPort)commPort;

// 设置端口参数(波特率,数据位,停止位,奇偶性[校验])

serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

// 获取当前串口(串行端口)的输入输出流

InputStream is = serialPort.getInputStream();

OutputStream os = serialPort.getOutputStream();

// 利用上面的输入输出流创建两个单独的线程进行报文的传送与接收

(new Thread(new SerialReadThreadBody(is))).start();

(new Thread(new SerialWriteThreadBody(os))).start();

}

// 否则当前端口不是串行端口,或者串口打开失败

else {

System.out.println("当前端口不是串行端口,或发生未知错误,导致串口打开失败!");

}

}

}

/**

* 创建一个串读线程体内部类

* 作用:从设备读报文到上位机

* @author 都颜汗

*

*/

public class SerialReadThreadBody implements Runnable {

private InputStream is;

// 创建一个构造,用于获取输入流对象

public SerialReadThreadBody(InputStream is) {

this.is = is;

}

@Override

public void run() {

// 操作:从输入流中读取报文,传给上位机,显示出来

byte[] buf = new byte[1024];

int len = -1;

try {

String temperatureHexStr = "";

while((len = this.is.read(buf)) > -1)

{

if(len == 1)

System.out.println("当前默认地址:" + SerialCommUtils.byte2HexStr(buf[0]));

else

for(int i = 0; i < len; i++)

{

System.out.print(SerialCommUtils.byte2HexStr(buf[i]) + " ");

if(i == 2 || i == 3)

{

temperatureHexStr += SerialCommUtils.byte2HexStr(buf[i]);

}

if(i == len-1)

{

// 打印温度

System.out.println("\n当前获取到的温度是:" + SerialCommUtils.hexStr2Integer(temperatureHexStr)*0.1 + "°C");

}

}

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

/**

* 创建一个串写线程体内部类

* 作用:从上位机写报文到设备

* @author 都颜汗

*

*/

public class SerialWriteThreadBody implements Runnable {

OutputStream os;

public SerialWriteThreadBody(OutputStream os) {

this.os = os;

}

// 0 3 0 0 0 2 197 218

@Override

public void run() {

// 操作:从输出流中将报文传给设备,然后设备做出响应,单独通过串读线程将结果返回给上位机

try {

Scanner sc = new Scanner(System.in);

String input = "";

while(!(input = sc.next().trim()).equals(""))

{

this.os.write(SerialCommUtils.hexStr2Integer(input));

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

public static void main (String[] args)

{

try {

new MyTwoWaySerialComm().connect("COM4");

} catch (Exception e) {

e.printStackTrace();

}

}

}

SerialCommUtils.java [对输入输出进行处理的工具类]

/**

* 串行通信工具类

* @author 都颜汗

*

*/

public class SerialCommUtils {

/**

* 将一个十六进制字符串转换成一个十进制数值

* @param hexStr 十六进制字符串,每个字符串包含两个十六进制字符,每个字符串表示一个字节

* @return 十进制整数

*/

public static int hexStr2Integer(String hexStr) {

// 先获取字符串长度

int len = hexStr.length();

int sum = 0;

// 从高位到低位挨个儿计算

for(int i = 0; i < len; i++)

{

// 获取当前位的十六进制数对应的十进制值

int curNum = SerialCommUtils.hexChar2Integer(hexStr.charAt(i));

sum += curNum * Math.pow(16, len-i-1);

}

return sum;

}

/**

* 将一个十六进制字符转换成一个十进制数值

* @param c 一个十六进制字符

* @return c这个十六进制字符对应的十进制整数

*/

public static int hexChar2Integer(char c){

if(c >= '0' && c <= '9')

{

return c-48;

}

else if((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))

{

if(c >= 'a')

return c-87;

else

return c-55;

}

return -1;

}

/**

* 将一个十进制数值转成一个十六进制字符

* @param n 是一个十进制数值,合理范围为0~15

* @return返回一个十六进制字符

*/

public static char int2HexChar(int n)

{

if(n <=9 && n >= 0)

{

return (char)(n+48);

}

else if(n > 9 && n <= 15)

{

switch (n) {

case 10: return 'A';

case 11: return 'B';

case 12: return 'C';

case 13: return 'D';

case 14: return 'E';

case 15: return 'F';

default:

break;

}

}

return '■';

}

/**

* 将一个字节转换成一个字符串

* @param n 是待转换的字节

* @return返回一个包含两个十六进制字符的字符串

*/

public static String byte2HexStr(byte b)

{

// 首先,从设备返回的字节可能是个负值,先将其转换成一个不带符号的正值,放到int中保存

int tmp = b & 0xFF; // 这里利用按位与操作

int before = tmp/16;

int after = tmp%16;

String ret = "" + SerialCommUtils.int2HexChar(before) + SerialCommUtils.int2HexChar(after);

return ret;

}

}

程序运行示例:

本文参考文档&资源:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。