C# 回显/调试时顺序颠倒

C# 回显/调试时顺序颠倒,c#,arrays,arduino,uart,serial-communication,C#,Arrays,Arduino,Uart,Serial Communication,我试图将数据从VS Windows窗体发送到Arduino,但我的数据一直在镜像。我不确定这是否与缓冲区有关。如果我的理解是正确的,它应该与缓冲区无关,也与我的代码读/写数据无关,这是一个时间问题?缓冲区类似于系统的队列。因为它是FIFO,我初始化的顺序,所以它的顺序是相同的 我找到了这篇文章,但我不确定它是否适用。声明为共享同一元素时,在head和tail中。这是否适用于常规缓冲区?我假设由于是FIFO,头部和尾部不会共享相同的元素。 这似乎就是我所说的,但我不认为我在技术上使用了2个缓冲区

我试图将数据从VS Windows窗体发送到Arduino,但我的数据一直在镜像。我不确定这是否与缓冲区有关。如果我的理解是正确的,它应该与缓冲区无关,也与我的代码读/写数据无关,这是一个时间问题?缓冲区类似于系统的队列。因为它是FIFO,我初始化的顺序,所以它的顺序是相同的

我找到了这篇文章,但我不确定它是否适用。声明为共享同一元素时,在head和tail中。这是否适用于常规缓冲区?我假设由于是FIFO,头部和尾部不会共享相同的元素。 这似乎就是我所说的,但我不认为我在技术上使用了2个缓冲区

比如说,

String a = "1";
String b = "2";
String c = "3";
String d = "4";
String e = "5";
String f = "6";
String g = "7";
String h = "8";
String[] sendchar = new String [] {a, b, c, d, e, f, g, h};
因此,当我发送数据时,缓冲流应该是,从右开始是第一个元素,从左开始是最后一个元素;“h、g、f、e、d、c、b、a”将首先发送a,然后发送b等

目前,当我发送数据并将其回显时,我会按照相反的顺序发送“a,b,c,d,e,f,g,h”,但返回“h,g,f,e,d,c,b,a”

我通过读取数据接收数据,然后将其存储到数组中,复制数据,然后访问复制数组中的元素。这样就可以保留数据顺序

while (Serial.available() > 0 && newData == false)
{
    rb = Serial.read();

    if (rb != endMarker)
    {
        receivedChar[ndx] = rb;
        copyarray[ndx] = receivedChar[ndx];
            ndx++;

如何获取数据并将其发送到Arduino

    void loop()
{
    recvWithEndMarkers();//get Data
    Serial.flush();//Clear Input buffer
    delay(10);//delay
    testblink();//Test blink
    //blink();
    echo();//echo data back
    Serial.flush();
    delay(2000);
}
void echo()
{
    for (int b = 0; b <= 7; b++)
    {
        Serial.write(copyarray[b]);// Send b'th element of array
        delay(50);
        Serial.write("\n");//newline character terminates read
    }


void recvWithEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char endMarker = '}';
byte rb;
byte comp;

while (Serial.available() > 0 && newData == false)
{
    rb = Serial.read();//read data from input buffer

    if (rb != endMarker)//not end marker
    {
        receivedChar[ndx] = rb;//store data into array index
        copyarray[ndx] = receivedChar[ndx];//copy data
        ndx++;//next index
        if (ndx >= numBytes)
        {
            ndx = numBytes - 1;
        }
    }
    else//endmarker
    {
        receivedChar[ndx] = '}'; // terminate the string
        recvInProgress = false;
        ndx = 0;//reset ndx
    }


    }
}
void循环()
{
recvWithEndMarkers();//获取数据
Serial.flush();//清除输入缓冲区
延迟(10);//延迟
testblink();//测试闪烁
//眨眼();
echo();//回显数据
Serial.flush();
延迟(2000年);
}
void echo()
{

对于(int b=0;b我发现您的代码至少有几个问题。首先,我假设您重置了Arduino,然后运行windows程序,对吗

阿杜伊诺:

  • 您的recvWithEndMarkers()可能会看到Serial.available()==0,因此请立即退出while循环
  • 当您将一个字符放入缓冲区时,您会增加ndx(好)。但是当ndx==numBytes时,您会将ndx设置为7。它可能应该设置为0
  • 另外,ndx是一个“静态的”,所以当你再次运行它时,它会保留它的值——我敢打赌这不是你想要的
  • 退出recvWithEndMarkers()函数时,将执行一个serial.flush(),这可能会导致丢失字符,尤其是在第一次之后
  • 然后,echo()例程将“发送”当时copyarray[]中的任何内容(在Arduino上不确定是0还是255,但可能不是您所期望的)
  • 如果您的循环代码在循环的顶部有刷新和延迟(可能超过2秒),您可以启动Arduino,然后启动VS程序,可能会得到更好的结果
在VS方面,我没有看到任何类似的情况,但是您没有共享打印接收到的数据的代码


祝你好运!

我很幸运,它以相反的顺序翻转,没有混乱?可能是顺序的八分之一是奇怪的,但通常是倒序的。如果你在这两个方面都显示多一点代码,那就很难看到问题。比如,如何发送字符串数组“sendChar”?ndx“init”是什么?endMarker是什么还有,很难说,但我看到的是一个简单的缓冲区,而不是一个环形缓冲区。UART接收双缓冲是一个低级的东西,可能不适用(Arduino库应该处理它,但我怀疑它使用了环形缓冲区)。当然,我想我所做的只是一个简单的缓冲区。1.为什么它会看到Serial.available()==0?唯一发生这种情况的是缓冲区中没有数据时?这是正常的?2.我设置了这种情况,以防缓冲区中有太多数据,这样数组就不会超出边界,它只会替换最后一个元素。我认为我不需要这个部分。3.我没有意识到这一点。我认为静态只允许在函数,但我认为通过将ndx重置为0,我可以避免它保留它的值?4.这是错误的位置吗?我认为它会很好,因为它会清除缓冲区并防止额外的数据5.回送例程在大部分情况下工作正常。它发送存储在数组第n个地址的元素,并在VS侧I上只需读取元素并打印它。它工作正常,只是地址0没有返回任何内容。6.刷新和延迟的位置是否有重大影响?我认为后处理会更好,因为它会使用数据,然后在完成后清除它,而不是使用数据,然后在再次使用之前清除它?我肯定会这样做仔细看看。在VS上打印接收到的数据的代码是recchar。我获取该数组并显示我想我应该使用编号的项目符号。re:#1-我会说“正常”是指尚未接收到任何数据。因此,当它开始时,未接收到任何数据,因此它将读取0。#3“静态”--是的,这是关于C的一个不好的/令人困惑的事情。在函数外部,它表示“非全局”,但在内部,它表示静态,与“自动”相反,它是静态的,并且会发生变化(除了这里,如果你消除静态,它每次都会被初始化).Re:#4,#5,#6--当我开始做连续剧时,我会拿一张纸,对折,记录每一面会发生什么。你还必须考虑会触发什么。例如,我认为你需要先启动Arduino,循环应该检查是否有可用的字符。如果没有,只需返回。如果是这样,那么延迟足够长的时间,让所有字符进入(可能是1秒),然后进入while循环。另一种完全不同的方法是让loop()查看是否有字符,如果没有,退出,如果有,保存,并在满时发送。
port = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
        port.Open();
        for (int a = 0; a <= 7; a++)
        {
            port.Write(sendchar[a]);
            Thread.Sleep(50);
        }
        Thread.Sleep(50);
        port.DiscardOutBuffer();
        String[] recchar = new String[8];
        while (port.BytesToRead != 0)
        {

            for (int a = 0; a <= 7; a++)
            {
                recchar[a] = port.ReadLine();
                Thread.Sleep(50);
            }
        }
        port.DiscardInBuffer();