您好,欢迎来到平阳县妙观科技有限公司官方网站!主营温湿度记录仪温湿度变送器新款蓝牙版TH20BL火热畅销中!电联18601064199.

USB HID 连接TH20BL温湿度计读取实时温湿度的JAVA例子

import com.codeminders.hidapi.ClassPathLibraryLoader;
import com.codeminders.hidapi.HIDDeviceInfo;
import com.codeminders.hidapi.HIDManager;
import com.codeminders.hidapi.HIDDevice;

public class USBHIDExample {

    public static void main(String[] args) {
        try {
            ClassPathLibraryLoader.loadNativeHIDLibrary();
            HIDManager hidManager = HIDManager.getInstance();

            HIDDeviceInfo[] devices = hidManager.listDevices();
            HIDDevice thDevice =  getOneTHDevice(devices);

            GetRealtimeTH(thDevice);

            if(thDevice !=null) {
                thDevice.close();

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static HIDDevice  getOneTHDevice(HIDDeviceInfo[] devices)
    {
        HIDDeviceInfo hidDeviceInfo = null;
        for (HIDDeviceInfo deviceInfo : devices) {
            String deviceName = deviceInfo.getProduct_string();
            //温湿度的usb设备名称里面有 HHW字符串
            if(deviceName !=null && deviceName.contains("HHW")) {
                System.out.println(deviceName);
                hidDeviceInfo = deviceInfo;
                break;
            }

        }
        if(hidDeviceInfo != null)
        {
           try {

               HIDDevice hd = hidDeviceInfo.open();
               return hd;

           }
           catch (Exception e) {
               e.printStackTrace();
           }
        }
        return  null;
    }

    public  static  void  GetRealtimeTH(HIDDevice hidDevice)
    {
        // Convert the hexadecimal string to bytes
        //      8bytes  01 默认站号 04 功能码  00 00 02 数据个数  71 CB  CRC。 这里以站号1做的例子,如果其他站号,指令要修改
        //00 00 08 01 04 00 00 00 02 71 CB
        byte[] dataToSend = Helper.StrToHexByte("00000801040000000271CB");
        try {
            hidDevice.write(dataToSend);

            // Receive data from the device
            byte[] receivedData = new byte[11];

            hidDevice.read(receivedData);
            String receiveData = Helper.byteToHexStr(receivedData);
            System.out.println(Helper.byteToHexStr(receivedData));
            parseRealtimeTH(receiveData);

        }
        catch (Exception e) {
            e.printStackTrace();
        }





    }

    private static void parseRealtimeTH(String s) {
        int len = Integer.parseInt(s.substring(0, 1));
        if (len == 9) {
            String validData = s.substring(1, len * 2 + 1);
            System.out.println(validData);
            float t = Helper.ConvertHexToSInt(validData.substring(6, 10)) / 10.0f;
            float h = Helper.ConvertHexToSInt(validData.substring(10, 14)) / 10.0f;
            System.out.println("实时温度:" + t + ", 实时湿度:" + h);
        }
    }
}

 

 

 

import java.math.BigInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public  class Helper {
    //16进制字符串转化为16进制byte数组
    public static byte[] StrToHexByte(String hexString)
    {
        if (IsNullOrEmpty(hexString))
        {
            return null;
        }
        hexString=hexString.toUpperCase();
        int length = hexString.length()/2;
        char[] hexChars = hexString.toCharArray();
        byte[] d= new byte[length];
        for(int i = 0; i < length; i++)
        {
            int pos = i * 2;
            d[i] = (byte)(charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }

        return d;
    }




    private static byte charToByte(char c)
    {
        return (byte)"0123456789ABCDEF".indexOf(c);
    }

    // byte[] to HexString
    public static String byteToHexStr(byte[] bytes)
    {
        /*在Java中,new BigInteger(1, bytes).toString(16)和手动迭代字节数组并转换为16进制字符串的方法之间的区别在于处理字节数组中的前导零。
new BigInteger(1, bytes).toString(16)会忽略字节数组中的前导零,导致生成的16进制字符串不包含前导零。
手动迭代字节数组并转换为16进制字符串的方法会保留字节数组中的前导零,生成的16进制字符串会包含前导零。
因此,如果您希望保留字节数组中的前导零,可以使用手动迭代字节数组的方法。如果您希望忽略前导零,可以使用new BigInteger(1, bytes).toString(16)方法。选择哪种方法取决于您的需求和预期的结果。
*/

       String result = new BigInteger(1,bytes).toString(16);
       return result;
//       StringBuilder sb = new StringBuilder();
//       for(byte b:bytes){
//           sb.append(String.format("%02x",b));
//       }
//       return sb.toString();

    }

    /// <summary>
    /// 将16进制转换为有符号的10进制
    /// </summary>
    /// <param name="hexstr"></param>
    /// <returns></returns>
    public static String ConvertHexToSIntStr(String hexstr)
    {

        if (hexstr.startsWith("0x"))
        {
            hexstr = hexstr.substring(2);
        }

        //如果不是有效的16进制字符串或者字符串长度大于16或者是空,均返回NULL

        if (!IsHexadecimal(hexstr) || hexstr.length() > 16 || IsNullOrEmpty(hexstr))
        {
            return null;
        }

        if (hexstr.length() > 8)
        {
           return String.valueOf(Integer.valueOf(hexstr,16).longValue());
        }
        else if (hexstr.length() > 4)
        {
            return String.valueOf(Integer.valueOf(hexstr,16).intValue());

        }
        else
        {
            return String.valueOf(Integer.valueOf(hexstr,16).shortValue());

        }


    }

    public static  long ConvertHexToSInt(String hexstr)
    {
        if (hexstr.startsWith("0x"))
        {
            hexstr = hexstr.substring(2);
        }

        //如果不是有效的16进制字符串或者字符串长度大于16或者是空,均返回NULL

        if (!IsHexadecimal(hexstr) || hexstr.length() > 16 || IsNullOrEmpty(hexstr))
        {
            return 99999;
        }
        if (hexstr.length() > 8)
        {
            return Integer.valueOf(hexstr,16).longValue();
        }
        else if (hexstr.length() > 4)
        {
            return Integer.valueOf(hexstr,16).intValue();

        }
        else
        {
            return Integer.valueOf(hexstr,16).shortValue();

        }
    }


    //one byte
    public static String ConverIntToHexStr2(int t)
    {
        //显示为2个16进制字符
        return String.format("%02x",t);
    }

    //two byte
    public static String ConverIntToHexStr4(int t)
    {
        String rs = "";  //leng 4;

        //显示为4个16进制字符
        if (t >= 0) {
            rs= String.format("%04x",t);
        }
        else
        {
           //负数显示处理(这个是根据实际运行中显示的数据长度进行的处理),负数是4个字节表示,高2位为ffff
           String j = String.format("%04x",t);
           rs= j.substring(j.length()/2);

        }
        //返回末尾4个字符
       return rs.substring(rs.length()-4).toUpperCase();

    }

    /// <summary>
    /// 判断是否是十六进制格式字符串
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static boolean IsHexadecimal(String str)
    {
        String PAT =  "[A-Fa-f0-9]+$";
        return Pattern.matches(PAT, str);

    }

    public  static  boolean IsNullOrEmpty(String str)
    {
        if(str==null || str.length() == 0)
            return true;
        return  false; 
    }

    //标准modbus crc 2个字节 低前高后
    public static  int crc16_modbus(byte[] modbusdata, int length)
    {
        int i, j;
        int crc16 =  0x0000ffff;
        for (i = 0; i < length; i++)
        {
            crc16 ^= ((int)modbusdata[i]&0x000000ff);
            for (j = 0; j < 8; j++)
            {
                if ((crc16 & 0x00000001) == 1)
                {
                    crc16 = (crc16 >> 1) ^ 0x0000a001;
                }
                else
                {
                    crc16 = crc16 >> 1;
                }
            }
        }

        //little在前,high在后
        return ((crc16 & 0xff) << 8) + (crc16 >> 8);

    }
    //计算crcm
    public static int CRC16(String s)
    {
        byte[] a = Helper.StrToHexByte(s);
        int len = a.length;
        int crc = Helper.crc16_modbus(a, len);
        return (crc + 4660);

    }

}