在不使用 Arduino 中的 String 对象的情况下将二进制数据转换为其等效的 ASCII
Convert binary data to its ASCII equivalent without using String object in Arduino
我正在使用 Arduino。我有以下代码将二进制数据转换为其等效的 ASCII。它使用字符串对象。
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 对象但完成相同的 objective?
纯 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"
格式以获得大写的十六进制数字。
简单地转换每个数字。
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] = '[=10=]'; // terminate the string
Arduino 可能无法存储 4KB 的数据(ATmega328P 上的 SRAM 只有 2KB),如果缓冲区太大,请减小缓冲区大小。
你可以这样使用:
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。我有以下代码将二进制数据转换为其等效的 ASCII。它使用字符串对象。
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 对象但完成相同的 objective?
纯 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"
格式以获得大写的十六进制数字。
简单地转换每个数字。
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] = '[=10=]'; // terminate the string
Arduino 可能无法存储 4KB 的数据(ATmega328P 上的 SRAM 只有 2KB),如果缓冲区太大,请减小缓冲区大小。
你可以这样使用:
char * append_hex(char *out, uint8_t value)
{
static const char digits[] = "0123456789abcdef";
*out++ = digits[value >> 4];
*out++ = digits[value & 0xf];
return out;
}
然后在循环中调用它,在每次连续调用时传递它的返回值。如果需要,您可以在调用之间添加分隔符。
记得在完成后以 0 结束字符串。