android 蓝牙编程重点---如何发送和接收16进制数据

与蓝牙模块通信最重要的地方就是数据的发送和接收,因为是底层的操作,所以更多是发送16进制数据。

进制转换是我们程序员的必修课,属于基本素质。这里需要的是将字节数组转化为16进制字符串,方法都是通用的:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. public static String bytesToHexString(byte[] bytes) {  
  2.        String result = "";  
  3.        for (int i = 0; i < bytes.length; i++) {  
  4.            String hexString = Integer.toHexString(bytes[i] & 0xFF);  
  5.            if (hexString.length() == 1) {  
  6.                hexString = '0' + hexString;  
  7.            }  
  8.            result += hexString.toUpperCase();  
  9.        }  
  10.        return result;  
  11.    }  

     接下来就是发送数据。

     发送数据非常简单,之前有关于蓝牙编程的博文已经讲到了,http://www.cnblogs.com/wenjiang/p/3200138.html,这里只讲重要的一点:大容量字节数组的发送。

     我们需要发送64个字节的数组,如果一次性发送过去,单片机那里可能无法及时处理以致没有任何回应,因为单片机那里是设置了数据接收的延时时间。要想畅通的与蓝牙模块通信,考虑这个时间差非常重要。调整字节的发送速率,就成为非常关键的一步。值得注意的是,数据的发送是非常快的,就是因为这样才会导致单片机那里无法及时处理,所以,每次发送后的延时是非常重要的。我们单片机那里的延时是10毫秒,所以我们选择发送完每个字节后就延时10毫秒再发下个字节。

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. for (byte b : bytes) {  
  2.      out.write(b);  
  3.      Thread.sleep(10);  
  4.  }  

具体的延时时间和字节发送速率得看单片机那里程序的设置。
     在使用InputStream的时候,必须注意,InputStream的读取是阻塞的。这点在一般的情况下是不会影响到我们的程序,但是记住这个情况对于代码的设计是非常重要的,尤其是在考虑用户体验的时候。

     无参数的read()是每次只从流中读取一个字节,这种做法效率非常低,但是简单,像是读取整数值这种情况,使用read()就非常好,但如果是16进制字符串呢?使用InputStream.read(byte[] b)或者InputStream.read(byte[] b,int off,int len)方法,这样一次就能读取多个字节。

      如果是读取多个字节,我们常常使用InputStream.available()方法来获取数据流中可读字节的个数。读取本地数据的时候,该方法发挥得非常好,但如果是读取非本地数据,就可能出现字节遗漏的问题,像是要读取100个字节,可能就是90个,甚至是0个。

      出现0个的情况就是单片机那边没有响应或者字节还没发送过来,这时我们就需要一个循环来保证我们能够拿到数据:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. int count = 0;  
  2.   while (count == 0) {  
  3.    count = in.available();  
  4.   }  
  5.   byte[] bytes = new byte[count];  
  6.   in.read(bytes);  

但像是上面的90个字节的情况就是字节遗漏。对于这种情况,解决方法也很简单:

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. byte[] bytes = new byte[count];  
  2.   int readCount = 0// 已经成功读取的字节的个数  
  3.   while (readCount < count) {  
  4.    readCount += in.read(bytes, readCount, count - readCount);  
  5.   }  
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 ESP-IDF 中,可以使用 uart_write_bytes() 函数发送 16 进制数据,使用 uart_read_bytes() 函数接收 16 进制数据。 例如,以下代码片段演示了如何发送接收 16 进制数据: ```c // 设置串口参数 uart_config_t uart_config = { .baud_rate = 115200, .data_bits = UART_DATA_8_BITS, .parity = UART_PARITY_DISABLE, .stop_bits = UART_STOP_BITS_1, .flow_ctrl = UART_HW_FLOWCTRL_DISABLE }; // 初始化串口 uart_param_config(UART_NUM_0, &uart_config); uart_set_pin(UART_NUM_0, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); uart_driver_install(UART_NUM_0, 1024, 0, 0, NULL, 0); // 发送 16 进制数据 uint8_t data[] = {0x12, 0x34, 0xAB, 0xCD}; uart_write_bytes(UART_NUM_0, (const char*)data, sizeof(data)); // 接收 16 进制数据 uint8_t rx_buffer[4]; uart_read_bytes(UART_NUM_0, rx_buffer, sizeof(rx_buffer), portMAX_DELAY); ``` 在以上代码中,我们首先使用 uart_param_config() 函数设置串口参数,然后使用 uart_set_pin() 函数将串口引脚设置为默认值,最后使用 uart_driver_install() 函数初始化串口。 接着,我们使用 uart_write_bytes() 函数发送一个包含 4 个字节的 16 进制数据数组。 最后,我们使用 uart_read_bytes() 函数接收 4 个字节的 16 进制数据,并将其存储在 rx_buffer 数组中。请注意,此函数将一直等待,直到收到指定数量的字节。如果不希望等待,可以将最后一个参数设置为一个超时值(以毫秒为单位)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值