I need to send a Hex string over the serial to a device, I do that now like this:
byte[] c = new byte[3];
c[0] = 0x57;
c[1] = 0x30;
ComPort.Write(c,0,c.Length );
Now I need to convert a value of int like 30 to c[1] = 0x30 or a int value of 34 gives c[1] = 0x34.
I hope you see what I mean.
So how can I mange this?
This format is called binary-coded decimal. For two-digit numbers, integer-divide by ten and multiply by sixteen, then add back the remainder of the division by ten:
int num = 45;
int bcdNum = 16*(num/10)+(num%10);
Another way to do this could be
c[1] = Convert.ToByte(num.ToString(), 16);
suppose int Data=2821; was to send over COM Port:
c[0]= Convert.ToByte(data & 0x00FF);
c[0]= Convert.ToByte(data & 0xFF00) >> 8);
ComPort.Write(c,0,c.Length );
int num = 1366;
string bcdNum = num.ToString("X");
if (bcdNum.Length < 2)
bcdNum = "0" + bcdNum;
byte[] bytes_str=Enumerable.Range(0, bcdNum.Length).Where(x => x % 2 == 0).Select(x => Convert.ToByte(bcdNum.Substring(x, 2), 16)).ToArray();
Related
I have one byte of data and from there I have to extract it in the following manner.
data[0] has to extract
id(5 bit)
Sequence(2 bit)
HashAppData(1 bit)
data[1] has to extract
id(6 bit)
offset(2 bit)
Required functions are below where byte array length is 2 and I have to extract to the above manner.
public static int ParseData(byte[] data)
{
// All code goes here
}
Couldn't find any suitable solution to how do I make it. Can you please extract it?
EDIT: Fragment datatype should be in Integer
Something like this?
int id = (data[0] >> 3) & 31;
int sequence = (data[0] >> 1) & 3;
int hashAppData = data[0] & 1;
int id2 = (data[1] >> 2) & 63;
int offset = data[1] & 3;
This is how I'd do it for the first byte:
byte value = 155;
byte maskForHighest5 = 128+64+32+16+8;
byte maskForNext2 = 4+2;
byte maskForLast = 1;
byte result1 = (byte)((value & maskForHighest5) >> 3); // shift right 3 bits
byte result2 = (byte)((value & maskForNext2) >> 1); // shift right 1 bit
byte result3 = (byte)(value & maskForLast);
Working demo (.NET Fiddle):
https://dotnetfiddle.net/lNZ9TR
Code for the 2nd byte will be very similar.
If you're uncomfortable with bit manipulation, use an extension method to keep the intent of ParseData clear. This extension can be adapted for other integers by replacing both uses of byte with the necessary type.
public static int GetBitValue(this byte b, int offset, int length)
{
const int ByteWidth = sizeof(byte) * 8;
// System.Diagnostics validation - Excluded in release builds
Debug.Assert(offset >= 0);
Debug.Assert(offset < ByteWidth);
Debug.Assert(length > 0);
Debug.Assert(length <= ByteWidth);
Debug.Assert(offset + length <= ByteWidth);
var shift = ByteWidth - offset - length;
var mask = (1 << length) - 1;
return (b >> shift) & mask;
}
Usage in this case:
public static int ParseData(byte[] data)
{
{ // data[0]
var id = data[0].GetBitValue(0, 5);
var sequence = data[0].GetBitValue(5, 2);
var hashAppData = data[0].GetBitValue(7, 1);
}
{ // data[1]
var id = data[1].GetBitValue(0, 6);
var offset = data[1].GetBitValue(6, 2);
}
// ... return necessary data
}
i have this code
int[] i = new int[2]
i[0] = 0x13;
i[1] = 0x88;
here a value 5000 is converted to hex (1388) and put in an int array.
I want to make it so i can put in what i want with a int parameter. E.g. ``var represents decimal 6000 and it should convert it to hex (1770) and end up as
int[] i = new int[2]
i[0]= 0x17
i[1]= 0x70
in the array.
Try this
UInt16 input = 0x7017;
byte[] i = new byte[2];
i[0] = (byte)(input & 0xff);
i[1] = (byte)((input >> 8) & 0xff);
I'm having some difficulty reversing the following functions done before storing data to a device.
ss = enum + 16
u32ts = number << 8
u32timestamp = ss+u32ts
enum and number are the two vaules I'm trying to get back but I'm unawaire of what either of them are when I start with u32timestamp.
What I have tried to do is
uint temp = u32timestamp;
number = 0;
if (u32timestamp > 100)
{
number = (u32timestamp >> 8 & 8 );
temp = u32timestamp - number ;
}
enum = temp - 16;
But I keep getting out the incorrect values. Please help me fix this. enum is always between 16 and 21 but number can be positive any value.
// sample a and b
int a = 5, b = 7;
int ss = a + 16;
int u32ts = b << 8;
int u32timestamp = ss + u32ts;
// reversing...
int rev_b = u32timestamp >> 8;
int rev_ss = u32timestamp - (rev_b << 8);
int rev_a = rev_ss - 16;
var a = u32timestamp&0xFF;
var number= u32timestamp >>8;
var en = a-16;
the coding place "number" shifting eight bit to the left, so a regular 8 shift on the right will recover it by trashing the LS bits. Then we mask the lower bit to recover en.
public void Decode
{
uint u32timestamp = 31778;
var number = u32timestamp >> 8;
var temp = u32timestamp - (number << 8);
var en = temp - 16;
}
I have an integer that I need to convert to a four digit hex value.
For example, lets say the int value is 16. What I am looking for is a way to go from 16 to
0x00 0x10.
Any suggestions would be greatly appreciated!!!
Try this:
var input = 16;
var bytes = new byte[2];
bytes[0] = (byte)(input >> 8); // 0x00
bytes[1] = (byte)input; // 0x10
var result = (bytes[0] << 8)
| bytes[1];
// result == 16
Here's one with regular expressions, just for fun:
Regex.Replace(number.ToString("X4"), "..", "0x$0 ").TrimEnd();
Alternately, a little more general solution is to do it by byte array (then you can use this for strings or other data types)
public static string ByteArrayToString(byte[] ba)
{
string hex = BitConverter.ToString(ba);
return hex.Replace("-","");
}
int i = 39;
string str = "ssifm";
long l = 93823;
string hexi = ByteArrayToString(BitConverter.GetBytes(i));
string hexstr = ByteArrayToString(Encoding.Ascii.GetBytes(str));
string hexl = ByteArrayToString(BitConverter.GetBytes(l));
This returns them in a 'FF' format, you can add the '0x' yourself by adding this after the ToString() instead:
return "0x"+hex.Replace("-", " 0x");
Shift it! Mask it! Mask it! string.Format it!
int n = 16;
string.Format("0x{0:x2} 0x{1:x2}", (n & 0xff00) >> 8, n & 0xff); // 0x00 0x10
Here's a demo.
The x2 format specifier means a 2-digit hexadecimal value.
Okay, apparently you just want two bytes. Hexadecimal is not relevant here.
byte lowByte = (byte)(n & 0xff);
byte highByte = (byte)(n >> 8 & 0xff);
I have two bytes. I need to turn them into two integers where the first 12 bits make one int and the last 4 make the other. I figure i can && the 2nd byte with 0x0f to get the 4 bits, but I'm not sure how to make that into a byte with the correct sign.
update:
just to clarify I have 2 bytes
byte1 = 0xab
byte2 = 0xcd
and I need to do something like this with it
var value = 0xabc * 10 ^ 0xd;
sorry for the confusion.
thanks for all of the help.
int a = 10;
int a1 = a&0x000F;
int a2 = a&0xFFF0;
try to use this code
For kicks:
public static partial class Levitate
{
public static Tuple<int, int> UnPack(this int value)
{
uint sign = (uint)value & 0x80000000;
int small = ((int)sign >> 28) | (value & 0x0F);
int big = value & 0xFFF0;
return new Tuple<int, int>(small, big);
}
}
int a = 10;
a.UnPack();
Ok, let's try this again knowing what we're shooting for. I tried the following out in VS2008 and it seems to work fine, that is, both outOne and outTwo = -1 at the end. Is that what you're looking for?
byte b1 = 0xff;
byte b2 = 0xff;
ushort total = (ushort)((b1 << 8) + b2);
short outOne = (short)((short)(total & 0xFFF0) >> 4);
sbyte outTwo = (sbyte)((sbyte)((total & 0xF) << 4) >> 4);
Assuming you have the following to bytes:
byte a = 0xab;
byte b = 0xcd;
and consider 0xab the first 8 bits and 0xcd the second 8 bits, or 0xabc the first 12 bits and 0xd the last four bits. Then you can get the these bits as follows;
int x = (a << 4) | (b >> 4); // x == 0x0abc
int y = b & 0x0f; // y == 0x000d
edited to take into account clarification of "signing" rules:
public void unpack( byte[] octets , out int hiNibbles , out int loNibble )
{
if ( octets == null ) throw new ArgumentNullException("octets");
if ( octets.Length != 2 ) throw new ArgumentException("octets") ;
int value = (int) BitConverter.ToInt16( octets , 0 ) ;
// since the value is signed, right shifts sign-extend
hiNibbles = value >> 4 ;
loNibble = ( value << 28 ) >> 28 ;
return ;
}