在 Arduino 中不使用 String 对象将二进制数据转换为其 ASCII 等价物

Posted

技术标签:

【中文标题】在 Arduino 中不使用 String 对象将二进制数据转换为其 ASCII 等价物【英文标题】:Convert binary data to its ASCII equivalent without using String object in Arduino 【发布时间】:2016-08-16 11:00:49 【问题描述】:

我正在使用 Arduino。我有以下代码将二进制数据转换为其 ASCII 等价物。它使用 String 对象。

static uint16_t index = 0;
static char buffer[1600]; //contains binary data 0x11, 0x22, 0x1, 0xa ...

String msg;
index = strlen(buffer);
for (i=0; i < index; i++)

    //Produce a zero in front for single digits. Examples, 0x5 transforms into 05, 0xa transforms into 0a
    if (buffer[i] <= 0x0F)
    
        msg += "0";
    

    msg += String(buffer[i], HEX); //msg contains the ASCII equivalent of buffer    

如何修改代码以不使用 String 对象但实现相同的目标?

【问题讨论】:

static uint16_t index = 0;for (i=0; i &lt; index; i++) 你确定这是正确的吗? 感谢您发现错误。 index 应该是缓冲区的长度。 【参考方案1】:

简单地转换每个数字。

static char digits[] = "0123456789abcdef"; // characters used to represent digits

static uint16_t index = 0;
static char buffer[1600]; //contains binary data 0x11, 0x22, 0x1, 0xa ...

static char msg[3201]; // 2 digits for each bytes and 1 terminating null-character

for (i=0; i < index; i++)

    //Produce a zero in front for single digits. Examples, 0x5 transforms into 05, 0xa transforms into 0a
    msg[i * 2] = digits[((unsigned char)buffer[i] >> 4) & 0xf];

    msg[i * 2 + 1] = digits[(unsigned char)buffer[i] & 0xf]; //msg contains the ASCII equivalent of buffer


msg[index * 2] = '\0'; // terminate the string

Arduino 可能无法存储 4KB 的数据(ATmega328P 上的 SRAM 只有 2KB),如果太多,请减少缓冲区大小。

【讨论】:

【参考方案2】:

纯C解决方案:

#include <stdio.h>
#include <stdlib.h>

int main()

const unsigned char bytes[] = 0x04, 0x55, 0x56, 0xce , 0xdf ;
int i;
int sz = sizeof(bytes);
char *result = (char*)malloc(sz*4+1);
char *current = result;

for (i = 0; i < sz; i++)

    sprintf(current,"%02x",bytes[i]);
    current += 2;

printf("Result : %s\n",result);
free(result);

结果:

045556cedf

您还可以通过"%02X" 更改"%02x" 格式以获取大写十六进制数字。

【讨论】:

【参考方案3】:

你可以这样使用:

char * append_hex(char *out, uint8_t value)

  static const char digits[] = "0123456789abcdef";
  *out++ = digits[value >> 4];
  *out++ = digits[value & 0xf];
  return out;

然后在循环中调用它,在每次连续调用时传递它的返回值。如果需要,您可以在调用之间添加分隔符。

记得在完成后以 0 结尾。

【讨论】:

以上是关于在 Arduino 中不使用 String 对象将二进制数据转换为其 ASCII 等价物的主要内容,如果未能解决你的问题,请参考以下文章

Java 中不可变对象 String 真的"完全不可改变"吗?

Arduino String类型字符串转char数组

Arduino关于长整形数据转换成String类型

Arduino char/char*/String数据类型转换

为啥 Invoke 在另一个类中不起作用

arduino 引用std::string 报错