回显/调试时顺序相反

时间:2018-10-03 19:57:36

标签: c# arrays arduino uart serial-communication

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

我找到了这篇文章,但不确定是否适用。在this example about UART Ring Buffer中,声明的头和尾共享相同的元素。这是否适用于常规缓冲区?我假设由于是FIFO,所以头部和尾部不会共享相同的元素。 这个Article on Double buffering似乎就是我在说的,但是我不认为我在技术上使用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
    }


    }
}

在VS方面

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();

1 个答案:

答案 0 :(得分:1)

我发现您的代码至少有几个问题。首先,我假设您重置了Arduino,然后运行Windows程序,对吧?

ARDUINO:

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

在VS方面,我看不到任何类似的东西,但是您没有共享用于打印接收到的数据的代码。

祝你好运!