环境: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 gnu.io.CommPort;

import gnu.io.CommPortIdentifier;

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;

}

}

程序运行示例:

本文参考文档&资源:

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

  1. java socket 工具包_java.net 包 Socket通信 工具类

    废话1000000字省略.........呵呵...... 首先是服务器端:FileServer.java package com.stars.windsystem.tool.utils; impor ...

  2. Android 蓝牙串口通信工具类 SeriaPortUtil 2.0.+

    原文地址:https://www.shanya.world/archives/2fd981ea.html SerialPortUtil 提示 最新版本 3.0.+ 已发布,其对比 2.0.+ 版本,A ...

  3. java 兑换码生成_java生成兑换码礼包码--工具类

    importjava.util.HashSet;importjava.util.Random;importjava.util.Set;public classGenSerial {private st ...

  4. java线程 睡眠_java如何编写线程睡眠工具类包括随机睡眠时长

    最后给大家贴下这个睡眠工具类的完整代码 public class Sleep { /** * 睡眠n毫秒 * @param time */ public static void threadSleep ...

  5. java练习案例_Java项目案例之---常用工具类练习

    常用工具类练习 1. 请根据控制台输入的特定日期格式拆分日期,如:请输入一个日期(格式如:**月**日****年),经过处理得到:****年**月**日 importjava.util.Scanner ...

  6. Java并发(六)——CAS、AQS、Lock、通信工具类

    文章目录 CAS.AQS.Lock.通信工具类 1 CAS 1.1 Unsafe类 1.2 Atomic包 2 AQS 3 Condition 4 ReentrantLock 4.1 公平锁部分源码 ...

  7. 基于c#的串口设备通讯c#项目工程含虚拟串口软件与串口通信工具(C#源码)

    利用pc与串口通讯,在工业领域使用的很多: 串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节.尽管比按字节(byte)的并行通信慢,但是串口可以在 ...

  8. java工具类获取文件扩展名与content-type、http与content-type映射关系

    java工具类获取文件扩展名与content-type.http与content-type映射关系 大家好,我是酷酷的韩~ 一.对应关系参考地址: http://doc.chacuo.net/cont ...

  9. java 自定义json解析注解 复杂json解析 工具类

    java 自定义json解析注解 复杂json解析 工具类 目录 java 自定义json解析注解 复杂json解析 工具类 1.背景 2.需求-各式各样的json 一.一星难度json[json对象 ...

最新文章

  1. 基于thinkphp的省略图便捷函数
  2. Keras实现seq2seq案例代码:Bi-LSTM
  3. MySQL高级 - 锁 - 锁的概述及分类
  4. 初学者选黑卡还是微单_明日之镜 十年索尼微单和他的镜头王国
  5. python函数的 全局变量与局部变量
  6. JQuery.Ajax用法
  7. [leetcode]5343. 多次求和构造目标数组
  8. spire.pdf系列文章
  9. n阶方阵的蛇形排列java_排列组合的模板算法
  10. IntelliJ IDEA 查看类结构,查看类图,继承关系,查看package包关系
  11. bzoj3453: tyvj 1858 XLkxc(拉格朗日插值)
  12. w讠ndows Boot Manager,Win10电脑无法开机提示Windows boot manager的解决方案
  13. libGDX-5:文本显示 BitmapFont 和 工具 hiero
  14. Linux下安装人大金仓数据库说明
  15. 从假装在腾讯,到真的360 —— 一个应届准PM的独白(面经干货)
  16. 程序员值得提升的沟通小技巧!
  17. Android 校正系统时间的三种解决方案
  18. 几种蓝屏分析及解决汇总
  19. iOS UITextView 光标位置
  20. 二叉树的五种遍历方式

热门文章

  1. 华为公布 HarmonyOS 3 升级最新进展;内部人士回应马斯克决定任命朱晓彤为特斯拉全球 CEO|极客头条
  2. c盘满了怎么办【保姆级操作】
  3. 【Qt编程】基于Qt的词典开发系列一--词典框架设计及成品展示
  4. 华为Mate 50 pro 配置信息
  5. PPT分屏放映操作小技巧
  6. 阿里云服务器续费流程(2023年新版教程)
  7. Mac下sublime text3列模式下插入顺序数字编号
  8. failed with initial frozen solve. Retrying with flexible solve. 什么意思?
  9. NCCloud OpenAPI 客户端调试工具
  10. 【数据结构】17-二叉排序树(BST)