The (wireless) mBus standard uses a number as equivalent to a manufacturer-string. Some examples are shown here: https://www.m-bus.de/man.html
Turning a manufacturer string like "IST" to the correct number 0x2674 is explained on the website for javascript, I turned it successfully into a c# function:
public static bool TryMANtoHEX(string man_str, out uint man_hex)
{
man_hex = 0;
if (man_str.Length != 3) return false;
if (!Regex.IsMatch(man_str, @"^[a-zA-Z] $")) return false;
man_str = man_str.ToUpper();
try
{
man_hex = ((uint)man_str[2] - 64);
man_hex = ((uint)man_str[1] - 64) * 32;
man_hex = ((uint)man_str[0] - 64) * 32 * 32;
} catch
{
return false;
}
return true;
}
But I am struggling to revert this function, so turning an number back to a string.
I tried the following code an it works for character 1 and 3 - but not for char 2:
public static bool TryHEXtoMAN(uint man_hex, out string man_str)
{
man_str = string.Empty;
char c1 = (char)((man_hex / 1024) 64);
char c2 = (char)((man_hex / 32) 64);
char c3 = (char)((man_hex % 32) 64);
char[] cs = { c1, c2, c3 };
man_str = new(cs);
return true;
}
For 0x2674 I would expect "IST", but get "IųT".
Any Ideas?
CodePudding user response:
Just use easier to read bit-masking:
char c1 = (char)(((man_hex & 0b111110000000000) >>10) 64);
char c2 = (char)(((man_hex & 0b000001111100000) >> 5) 64);
char c3 = (char)(((man_hex & 0b000000000011111) >> 0) 64);
char[] cs = { c1, c2, c3 };
The particular error in your code is in computing c2 as you are not masking higher bits (15-10). If you want to keep math instead bitwise:
char c2 = (char)((man_hex % 1024 / 32) 64);