Serial format string -HEX
Introduction
Serial communication relates generally to a process simulation data and a data transmission process, in general, we will send a series of instructions to the next crew
68 05 00 84 01 02 03
This example, we know that we are converted into corresponding character hex character display for indication ascii letters, but in the process we can use the string directly represents a character we want to write, then after receiving serial conversion ASCII code corresponding to the process data,
Here are some common conversion functions
Data Format
In our description
is given first or reference Wikipedia ACII detailed description
herein, we are using "abc123" as a character string in which each display represented
- Refers to a string the string "abc 123" that can be able to play out ascii character representation, since we can not break out portion of the character, or characters are not displayed, only the control commands for flawed string str = " abc123 "
- Char string array [] uchar [] refers to a data in the cpp, char storage type or a character uchar, we can use a digital representation -128-127 or 0-255, we do consider that an array of facilitating uchar subsequent processing uchar buffer = {97,98,99,49,50,51}
- Char * uchar * string pointer is a pointer type, generally points to the address of the first character string data, because we believe that for many functions in the process 0x00 '\ 0' is ended, the processing time as much as possible the length of the incoming uchar * buffer = buffer
- converting the hex string values into an array of strings inside the two hexadecimal values, then use the space division can be easily input commands, e.g. string command = "61 62 63 31 32 33"
Suitable such advantages and disadvantages, for example, we send to the lower machine using such a control command in a conventional Modbus control, typically in the serial input directly, then sent to hex, but if we need to test the corresponding data according to the two segments, filled txt text, each line of data is read, and then be able to convert the data to analog inputs and outputs ascii binary stream
68 13 00 85 11 12 21 22 31 32 00 00 01 00 00 02 00 00 03 88 FF 01 02 03 04 05 0F
Data format conversion
1. uchar data conversion and data byte char
char type data -128-127, uchar 0-255 type data are a byte, char data type of the first sign bit, the following there will be from 127 (01111111) +1 becomes -128 (1000 0000 ) transformation, then there will transform from -1 (1111 1111) to 0 (0000 0000), and can search the detailed char 溢出
with 数据补码
related content,
Therefore uchar -char interconversion may be considered in two parts
uchar of [0, 127] == char [0,127]
ucahr the [128, 255] == char [ -128, -1]
// uchar 数据转换 char >127 c1-256
char Utils_String::UChar2Char(uchar c1)
{
return static_cast<char>(c1 > 127 ? c1 - 256 : c1);
}
// char 类型转换 uchar <0 -- c1 +256
uchar Utils_String::Char2UChar(char c1)
{
return static_cast<uchar>((c1 < 0 ? 256 + c1 : c1));
}
2. hex conversion and digital
Hex hex characters generally represented, for convenience since we show, in turn represented by a hexadecimal 16 character is supplied 0-9 af 0-15, here not to consider capital letters, uppercase to lowercase equivalent AF af,
Since the type of data between uchar 0-256, can be expressed exactly two hexadecimal characters to represent, prefix 0x indicates hexadecimal characters, represents octal 0o 0d indicates decimal [0,255] == [0x00, 0xFF,]
we have established a conversion between characters 0-f and 0-15, there are two conversion mode a is mandatory if the conversion is determined, the other is the use of a certain arrangement of the code optimization table deal with
And a hex codes num interconversion
/**
* @fn int Utils_String::Hex2Num(const char ch)
*
* @brief 根据 各种情况 转换字母 一位字母 大于 48 的 +9 然后取后4位的值
* *
*
* @author IRIS_Chen
* @date 2019/12/16
*
* @param ch The ch
*
* @return An int
*/
int Utils_String::Hex2Num(const char ch)
{
//int res = (ch & '@' ? ch + 9 : ch) & 0x0F;
//LInfo("ch:{},res:{}", ch, res);
return (ch & '@' ? ch + 9 : ch) & 0x0F;
}
/**
* @fn char Utils_String::Num2Hex(int num, bool Up )
*
* @brief 将 0-15 转换成 0-F
*
* @author IRIS_Chen
* @date 2019/12/18
*
* @param num Number of
* @param Up True to up
*
* @return The total number of 2 hexadecimal
*/
char Utils_String::Num2Hex(int num, bool Up /* = true */)
{
char res;
if (num >= 10 && num <= 15)
{
res = num - 10 + (Up ? 'A' : 'a');
}
else
res = num + '0';
return res;
}
And a hex codes num interconversion
2 and hex conversion uchar
/**
* @fn uchar Utils_String::Hex2Uchar(const std::string & str)
*
* @brief Hexadecimal 2 uchar 将两个 hex 字符 转换成 0-256
*
* @author IRIS_Chen
* @date 2019/12/18
*
* @param str The string 默认初始两位字符 FF == 255 00 = 0 0D = 14
*
* @return An uchar
*/
uchar Utils_String::Hex2Uchar(const std::string & str)
{
uchar res = 0;
for (const auto &s:str)
{
res = (res << 4) + Hex2Num(s);
}
return res;
}
/**
* @fn std::string Utils_String::Num2Hex(uchar num, bool Up)
*
* @brief Number 2 hexadecimal 得到的结果只有 小写
*
* @author IRIS_Chen
* @date 2019/12/18
*
* @param num Number of
* @param Up True to up
*
* @return The total number of 2 hexadecimal
*/
std::string Utils_String::Num2Hex(uchar num, bool Up)
{
std::map<int, char> t_base = {
{ 8,'o' },
{ 10,'d' },
{ 16,'x' } };
if (!t_base.count(base))
return "";
// 使用 sprintf 格式化输出, 将数字 转换成相应的进制值
std::string format = "%0" + std::to_string(width) + t_base.find(base)->second;
char *buf = new char[20];
sprintf(buf, format.c_str(), num);
std::string res=std::string(buf);
// 转换大小写
return Up ? StringUpper(res) : StringLowwer (res);
}
3. given string into an array of strings
Due to the converted character string pointer rotation native
pointer may be used to process a native
/**
* @fn const uchar * Utils_String::String2Uchar(const std::string & str)
*
* @brief String 2 uchar
*
* @author IRIS_Chen
* @date 2019/12/16
*
* @param str The string
*
* @return Null if it fails, else a pointer to a const uchar
*/
const uchar * Utils_String::String2Uchar(const std::string & str)
{
return (uchar*)str.c_str();
}
/**
* @fn std::string Utils_String::Uchar2String(const uchar * buffer)
*
* @brief Uchar 2 string
*
* @author IRIS_Chen
* @date 2019/12/16
*
* @param buffer The buffer
*
* @return A std::string
*/
std::string Utils_String::Uchar2String(const uchar * buffer)
{
std::string str = (char*)buffer;
return str;
}
4. hex string conversion array of strings
Sequentially capturing two characters, it is converted to a stored data value to ucahr
Conversion hex string string array
/**
* @fn uchar * Utils_String::Hex2CharArr(uchar *&buffer, const std::string & str, bool flg_space)
*
* @brief Hexadecimal 2 character array hex 字符串 转换成 数组
*
* @author IRIS_Chen
* @date 2019/12/18
*
* @param [in,out] buffer [in,out] If non-null, the buffer
* @param str The string
* @param flg_space True to flg space hex 是否使用空格分割
*
* @return Null if it fails, else a pointer to an uchar
*/
uchar * Utils_String::Hex2CharArr(uchar *&buffer, const std::string & str, bool flg_space)
{
// 出错 只有两个值 默认不符合 操作
if (str.size() < 3) return nullptr;
// 默认够长 判断是否存在空格
if (str[2] == ' ') flg_space = true;
int step = flg_space ? 3 : 2;
buffer = new uchar[(str.size() + 1) / step +1 ];
std::string str2 = "";
for (int i = 0; i < static_cast<int>(str.size());)
{
uchar ch = Hex2Uchar(str.substr(static_cast<size_t>(i), 2));
// 根据是否有空格选择 移动
*(buffer + i/step) = ch;
i += step;
str2 += std::to_string((int)ch) + "-";
}
// LInfo("charArr:{}", str2);
return buffer;
}
/**
* @fn std::string Utils_String::CharArr2Hex(uchar * buffer, int length, int flg_space)
*
* @brief Character array 2 hexadecimal 数组 转换成 hex 字符
* * 将UCHAR 字符串依次转换成 string 字符串
*
* @author IRIS_Chen
* @date 2019/12/18
*
* @param [in,out] buffer If non-null, the buffer
* @param length The length
* @param flg_space The flg space
*
* @return A std::string
*/
std::string Utils_String::CharArr2Hex(uchar * buffer, int length, int flg_space)
{
std::string str = "";
// 读取数组中所有字符
for (int i = 0; i < length; i++)
{
str += Num2Hex(*buffer++);
// 如果开启空格的话 每两个字符 之间加入一个空格 最后一个不加
if (flg_space && i != length - 1)
str += " ";
}
return str;
}
More
Probably so much common conversion process, there is a separate transfer function string array, you may be used sprintf
formatted output, violence or cyclic modulo values to obtain a final result
Digital conversion and string can be a number ary
/**
* @fn std::string Utils_String::NumToString(int num, int width, int base)
*
* @brief Number to string 整型数据 前补 0 占位符显示 进制 为 8 10 16 如果超过给出的宽度 原始宽度显示
*
* @author IRIS_Chen
* @date 2019/12/3
*
* @param num Number of
* @param width The width
* @param base The base
*
* @return The total number of to string
*/
std::string Utils_String::NumToString(int num, int width, int base)
{
#if 0
// 保证 存在进制 只考虑 2 8 , 10 16 进制
static std::map<int, char> t_base = {
{ 2,'0' },
{ 8,'o' },
{ 10,'d' },
{ 16,'x' } };
if (!t_base.count(base))
return "";
// 二进制 特殊处理
if (base == 2)
{
std::string str_8 = NumToString(num, width, 8);
// 设置8进制 转2进制码表, 转换之后 去除前缀0 即可
static const std::vector<std::string> table = { "000","001","010","011","100","101","110","111" };
std::string str_2 = "";
for (auto s : str_8)
{
if(s =='0')
continue;
str_2 += table[s - '0'];
}
// 去掉前面所有的 0值 从1 开始
int pos = static_cast<int>(str_2.find_first_of('1'));
// #TODO(Schen00) 处理, 得到的长度小于width 的情况
return pos == std::string::npos ?"":str_2.substr (pos);
}
std::string format = "%0" + std::to_string(width) + t_base.find(base)->second;
char *buf = new char[20];
sprintf(buf, format.c_str(), num);
return std::string(buf);
#else
std::string res = "";
while (num)
{
res = base == 16 ? Num2Hex(num % base) : (num % base + '0') + res;
num /= base;
}
// 不足位 补0 足位 不删除
int cnt = width - res.size();
while (cnt--)
{
res = '0' + res;
}
return res;
#endif
}