目标数组不够长

时间:2019-02-15 11:26:31

标签: c# serial-port

我正在尝试从Arduino到Visual Studio中的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

1 个答案:

答案 0 :(得分: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);