我正在尝试在Visual Studio中从Arduino到C#进行串行通信。这是我的代码。我使用计时器来请求和接收数据。
private void timer1_Tick(object sender, EventArgs e)
{
isConnected = true;
port.Write("A");
int bytes = port.BytesToRead;
byte[] buffer = new byte[bytes];
port.Read(buffer, 0, bytes);
for (int i = 0; i < bytes; i++)
{
int potensio = BitConverter.ToInt32(buffer, 0);
string potString = Convert.ToString(potensio);
label1.Text = potString;
}
}
此行int potensio = BitConverter.ToInt32(buffer, 0);
出错
System.ArgumentException
HResult = 0x80070057
Message=Destination array is not long enough to copy all the items in the collection.Check array index and length.
Source= mscorlib
StackTrace:
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.BitConverter.ToInt32(Byte[] value, Int32 startIndex)
at SerialTest.Form1.timer1_Tick(Object sender, EventArgs e) in C:\Users\ThinkPad\source\repos\SerialTest\SerialTest\Form1.cs:line 73
at System.Windows.Forms.Timer.OnTick(EventArgs e)
at System.Windows.Forms.Timer.TimerNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at SerialTest.Program.Main() in C:\Users\ThinkPad\source\repos\SerialTest\SerialTest\Program.cs:line 19
K表;让我们试着解决这个问题;这里的问题是数据并不总是以你想要的漂亮整齐的方式到达。在您的情况下,您希望一次处理4个字节,所以:让我们尝试:
byte[] buffer = new byte[4];
int bytesBuffered = 0;
bool inProgress = false;
private void timer1_Tick(object sender, EventArgs e)
{
if (!inProgress) {
// presumably this means "send me the current data?"
inProgress = true;
port.Write("A");
}
// read whatever we still need to make 4, if available
int bytes = Math.Min(port.BytesToRead, 4 - bytesBuffered);
if (bytes <= 0) return; // nothing to do right now
// read the next few bytes, noting the offset
bytes = port.Read(buffer, bytesBuffered, bytes);
// TODO: check if bytes is <= 0 - if so, the port may have disconnected
bytesBuffered += bytes;
// check whether we have enough to update the UI
if (bytesBuffered == 4)
{
// we now have 4 bytes; update the UI, and reset
int potensio = BitConverter.ToInt32(buffer, 0);
string potString = Convert.ToString(potensio);
label1.Text = potString;
// and issue a new A next time
bytesBuffered = 0;
inProgress = false;
}
}
注意:如果你得到奇怪的结果,你有可能没有考虑“字节序” - 一个4字节的整数可以编码为“大端”或“小端”,你的CPU可以是“大端”或“小端” - 两者需要匹配。如果结果看起来非常大(或疯狂负面),请尝试在Array.Reverse(buffer)
调用之前添加ToInt32
,最好在BitConverter.IsLittleEndian
检查之后;即
// we now have 4 bytes; update the UI, and reset
if (BitConverter.IsLittleEndian) Array.Reverse(buffer); // fix endianness
int potensio = BitConverter.ToInt32(buffer, 0);
如果这给出了错误的结果:逆转它!
// we now have 4 bytes; update the UI, and reset
if (!BitConverter.IsLittleEndian) Array.Reverse(buffer); // fix endianness
int potensio = BitConverter.ToInt32(buffer, 0);