I have 2 floats f1
& f2
. I need to convert them into binary(e.g. 01010101 10000001 11110000 01011110, i.e.8 bits*4) then send them through a serial port. At the receiving end, after receiving these signals in binary, I need to convert them into float and display them as a string.
My questions are:
Is my conversion from float to binary correct?
When the signal is received, textbox3
only displays some random code while textbox4
is empty. Why is this?
My current codes are as below.
To send:
byte[] b1 = System.BitConverter.GetBytes(f1), b2 = System.BitConverter.GetBytes(f2);
if (serialPort.IsOpen)
{
serialPort.Write(b1, 0, 4);
serialPort.Write(b2, 0, 4);
}
To receive:
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
byte[] b = new byte[sp.BytesToRead];
sp.Read(b, 0, sp.BytesToRead);
Invoke(new Action(() => textBox3.AppendText(Encoding.UTF8.GetString(b))));
float newf = System.BitConverter.ToSingle(b, 0);
textBox4.Text = newf.ToString();
}
Several mistakes, you hope that you'll get the entire 'package' that was sent. Serial ports do not work that way. You'll have to wait until all 8 bytes were received. Encoding.UTF8
is quite inappropriate, it isn't text. Write something like this:
private byte[] Buffer = new byte[8];
private int Rcved = 0;
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
Rcved += sp.Read(Buffer, Rcved, 8 - Rcved);
if (Rcved < 8) return;
float f1 = BitConverter.ToSingle(Buffer, 0);
float f2 = BitConverter.ToSingle(Buffer, 4);
string txt3 = BitConverter.ToString(Buffer);
string txt4 = String.Format("{0}, {1}", f1, f2);
this.BeginInvoke(new Action(() => {
textBox3.AppendText(txt3 + Environment.NewLine);
textBox4.Text = txt4;
}));
Rcved = 0;
}
Beware a synchronization problem, your program can't properly start up when the device is busy sending, it will only have a 1 in 8 chance to start reading at the correct byte. Solving this requires a protocol, a very simple one is master-slave where the device doesn't send anything until it is explicitly asked to do so.
And beware of a fire-hose problem, your UI can freeze on the BeginInvoke() calls if they occur too frequently. In which case you need to improve the UI, no human is going to enjoy looking at a list of numbers flying by faster than he can possibly read anyway.