目标数组不够长

问题描述 投票:1回答:1

我正在尝试在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
c# serial-port
1个回答
1
投票

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);
© www.soinside.com 2019 - 2024. All rights reserved.