I'm not realizing what is wrong with my code, take a look:
C# code:
const int MOVE = 112;
MemoryStream m = new MemoryStream();
m.SetLength(4 + 1 + (1 + 1 + 1 + 1));
BinaryWriter bw = new BinaryWriter(m);
int id_ = getId();
bw.Write(Converter.GetBigEndian(id_));
sbyte eventMove = MOVE;
sbyte rowFromByte = 4;
sbyte colFromByte = 2;
sbyte rowToByte = 1;
sbyte colToByte = 3;
bw.Write(eventMove);
bw.Write(rowFromByte);
bw.Write(colFromByte);
bw.Write(rowToByte);
bw.Write(colToByte);
When I read on java I do:
ByteBuffer msg = an instance of ByteBuffer...
int id = msg.getInt();
byte event = msg.get();
byte rowFrom = msg.get();
byte colFrom = msg.get();
byte rowTo = msg.get();
byte colTo = msg.get();
Every time I read on java it reaches till the event ok.
Sometimes it works correctly, reads everything ok e.g if I put on c#:
sbyte rowFromByte = 12;
sbyte colFromByte = 2;
sbyte rowToByte = 1;
sbyte colToByte = 3;
It works, but if I put a value <= 7 on the first rowFromByte e.g:
sbyte rowFromByte = 4;
sbyte colFromByte = 2;
sbyte rowToByte = 1;
sbyte colToByte = 3;
the java code doesn't read the values correctly it reads:
rowFrom: -7, colFrom: 0, rowTo: -7, colTo: 0
SOLVED: the values above were printed wrongly (during the wrong time), because of that I thought there were problems with the code.
It prints the corrects values bellow:
rowFrom: 4, colFrom: 2, rowTo: 1, colTo: 3
On c# I use the Memorystream to get the bytes to send to java client:
MemoryStream message = the instance of memory stream...
bytesMessage = message.ToArray();
WHY putting a value <= 7 for rowFrom returns wrong bytes association on java?
There's something very weird or silly I'm not getting into.
I solved the problem.
The problem is that: there wasn't any problem with my code.
As I supposed this was a Silly stuff: I was printing the wrong variables on server.
I didn't know very well C# I posted this question on on stackoverflow.
Maybe this simple example can be useful for other people.
Related
I'm looking for C# method that's equivalent to PHP pack()
I've found lot of articles about this on Google, but the result is always different than using my PHP code when I've tried some code.
I have no idea.
Here's my PHP code which I'd like to transfer in C# code.
$binaryMagic = pack("n", 0xbabe);
This code should give you the same result:
string hex = "babe";
byte[] bytes = new byte[hex.Length / 2];
for (int i = 0; i < hex.Length; i += 2) {
bytes[i/2] = Convert.ToByte(hex.Substring(i, 2), 16);
}
string converted = System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length);
Console.WriteLine(converted);
I have written the following code in C# to get 16-bit twos compliment values over uart from 8 bit microcontroller. I am receiving data in bytes form. So I am combining the two bytes to form a 16-bit value. My issue is that my all values are becoming negative, but in reality some are negative some are not. Please tell me what is wrong of the following code that I am doing:
int t = 0;
int bytes = serialPort1.BytesToRead;
byte[] buffer = new byte[bytes];
serialPort1.Read(buffer, 0, bytes);
float [] buffer2 = new float[bytes];
for(int i=0;t< buffer.Length;i++)
{
buffer2[i]= ~(((buffer[t]<< 8) | buffer[t+1]) - 1);
t = t + 2;
}
I'm currently working on a master/slave where the Master is a C# program and the Slave is an Arduino Uno. The Arduino is reading several values and is working as expected, but I'm having some troubles on the C# side. I'm reading 3 bytes from an AD converter (AD7680), which returns 3 bytes of data structured in the following way:
0000 | 16 bit number | 0000
My C# program is reading the returned value in a double, which is the expected value. BUT I didn't find out how to get rid of the last four 0's and obtain the 2 byte number I need.
What should be the best approach to get the right value without loosing data? I tried 'BitConverter' but it´s not what I'm expecting, and I have no clue how to proceed. I currently can´t attach the code unfortunately, but I could reference anything on it if needed.
Thanks for reading!
EDIT: This is the function on the C# side:
public double result(byte[] command)
{
try
{
byte[] buffer = command;
arduinoBoard.Open();
arduinoBoard.Write(buffer, 0, 3);
int intReturnASCII = 0;
char charReturnValue = (Char)intReturnASCII;
Thread.Sleep(200);
int count = arduinoBoard.BytesToRead;
double returnResult = 0;
string returnMessage = "";
while (count > 0)
{
intReturnASCII = arduinoBoard.ReadByte();
//string str = char.ConvertFromUtf32(intReturnASCII);
returnMessage = returnMessage + Convert.ToChar(intReturnASCII);
count--;
}
returnResult = double.Parse(returnMessage, System.Globalization.CultureInfo.InvariantCulture);
arduinoBoard.Close();
return returnResult;
}
catch (Exception e)
{
return 0;
}
}
And the Arduino function that communicates with it is this one:
unsigned long ReturnPressure(){
long lBuffer = 0;
byte rtnVal[3];
digitalWrite(SLAVESELECT , LOW);
delayMicroseconds(1);
rtnVal[0] = SPI.transfer(0x00);
delayMicroseconds(1);
rtnVal[1] = SPI.transfer(0x00);
delayMicroseconds(1);
rtnVal[2] = SPI.transfer(0x00);
delayMicroseconds(1);
digitalWrite(SLAVESELECT, HIGH);
// assemble into long type
lBuffer = lBuffer | rtnVal[0];
lBuffer = lBuffer << 8;
lBuffer = lBuffer | rtnVal[1];
lBuffer = lBuffer << 8;
lBuffer = lBuffer | rtnVal[2];
return lBuffer;
}
Okay, you have to do a few steps:
Firstly: Its much easier to save the bytes in an array like this:
byte Received = new byte[3];
for(int i = 0; i < 3; i++)
{
Received[i] = (byte)arduinoBoard.ReadByte();
}
After received the three bytes, shift it together (check if the three bytes are in the right order: Most significant byte is here at index 0)
UInt64 Shifted = (UInt64)(Received[0] << 16) | (UInt64)(Received[1] << 8) | (UInt64)(Received[0])
Now shift out the four ending zeros:
UInt64 Shifted = Shifted >> 4;
To find out, what your voltage is, you have to know the scale of your converter. The Data sheet says, "The LSB size is VDD/65536". You could define a constant
const double VDD = 5; //For example 5V
After that you can calculate your needed double with
return Shifted * (VDD / 65539); //Your voltage
Hope this helps.
The main problem is that I recive a binary number with only 10 bits in use from a SerialPort so I use this to receive the complete data:
byte[] buf = new byte[2];
serialPort.Read(buf, 0, buf.Length);
BitArray bits = new BitArray(buf);
The original idea for convert binary to int was this:
foreach (bool b in bits)
{
if(b){
binary += "1";
}
else{
binary+= "0";
}
}
decimal = Convert.ToInt32(binary, 2);
decimal = decimal >> 6;
binary is obviously a string, that works but I need to know if exists another solution, instead of the previuos code I try with this:
decimal = BitConverter.ToInt16(buf, 0);
But this only read the first 8 bits, I need the other 2 bits missing! If I change ToInt16 for a ToInt32
decimal = BitConverter.ToInt32(buf, 0);
The program stops for a System.ArgumentException: Destination array was not long enough...
What can I do?
You can just shift the values in the bytes so that they match, and put them together. If I got the use of bits right, that would be:
int value = (buf[0] << 2) | (buf[1] >> 6);
I'm trying to convert a bit of VC 6.0 C++ code to C#. Specifically, I'm parsing through a binary dat file and I've run into a problem converting this bit of code:
ar.GetFile()->Read(buf,sizeof(int));
memmove(&x,buf,4);
pEBMA->before_after = static_cast<enum EBMA_Reserve>(x);
pEBMA->method = static_cast<enum EBMA_Method>(x >> 4);
Here is some related code.
struct EBMA_Data *pEBMA = &EBMA_data;
typedef CArray<struct EBMA_Data,struct EBMA_Data&> EBMA_data;
enum EBMA_Reserve
{EBMA_DONT_RESERVE,
EBMA_BEFORE,
EBMA_AFTER
};
enum EBMA_Method
{EBMA_CENTER,
EBMA_ALL_MATERIAL,
EBMA_FRACTION,
EBMA_RESERVE
};
struct EBMA_Data
{double reserved;
double fraction;
enum EBMA_Method method : 4;
enum EBMA_Reserve before_after : 4;
};
I've read this thread here Cast int to Enum in C#, but my code isn't giving me the same results as the legacy program.
Here is some of my code in C#:
reserved = reader.ReadDouble();
fraction = reader.ReadDouble();
beforeAfter = (EBMAReserve)Enum.ToObject(typeof(EBMAReserve), x);
method = (EBMAMethod)Enum.ToObject(typeof(EBMAMethod), (x >> 4));
I do have an endianness problem so I am reversing the endianness like so.
public override double ReadDouble()
{
byte[] b = this.ConvertByteArrayToBigEndian(base.ReadBytes(8));
double d = BitConverter.ToDouble(b, 0);
return d;
}
private byte[] ConvertByteArrayToBigEndian(byte[] b)
{
if (BitConverter.IsLittleEndian)
{
Array.Reverse(b);
}
return b;
}
So then I thought that maybe the endianness issue was still throwing me off so here is another attempt:
byte[] test = reader.ReadBytes(8);
Array.Reverse(test);
int test1 = BitConverter.ToInt32(buffer, 0);
int test2 = BitConverter.ToInt32(buffer, 4);
beforeAfter = (EBMAReserve)test1;
method = (EBMAMethod)test2;
I hope I've given enough details about what I'm trying to do.
EDIT:
This is how I solved my issue, apparently the values I needed were stored in the first byte of a 4 byte segment in the binary file. This is in a loop.
byte[] temp = reader.ReadBytes(4);
byte b = temp[0];
res = (EBMAReserve)(b & 0x0f);
meth = (EBMAMethod)(b >> 4);
EDIT: It actually looks like the structure size of EBMA_Data is 17 bytes.
struct EBMA_DATA
{
double reserved; //(8 bytes)
double fraction; //(8 bytes)
enum EBMA_Method method : 4; //(this is packed to 4 bits, not bytes)
enum EMBA_Reserve before_after : 4; //(this too, is packed to 4 bits)
}
so your read code should look something more like this:
EBMA_Data data = new EBMA_Data;
data.reserved = reader.ReadDouble();
data.fraction = reader.ReadDouble();
byte b = reader.ReadByte();
data.method = (EBMAMethod)(b >> 4);
data.before_after = (EBMAReserve)(b & 0x0f);
Not 100% sure, but it looks like the code that does the shift x >> 4 bytes may be the underlying issue that's being overlooked. If the EBMAReserve is the lower 4 bits of x and EBMAMethod is the top 4 bits, maybe this code would work?
EBMAReserve res = (EBMAReserve)(x & 0x0f);
EBMAMethod meth = (EBMAMethod)(x >> 4);
I think that is what the : 4 means after the enumerations in the struct, it's packing the two enums into the structure as a single byte instead of 2 bytes.