函数每隔一次调用

时间:2017-08-18 19:11:27

标签: arduino serial-port buffer

我的以下功能从串口读取,处理数据并向用户显示信息。有趣的是,它似乎只在奇数编号实例上调用时才起作用。在偶数读取时,会发生超时情况。

如果用户调用此函数,则每10秒或更早调用一次。无论它被称为多久,它都会每隔一段时间都有效。

CODE:

bool SR(bool echo, int&value)
{ 
  bool valid;
  byte buf [2];
偶数电话red上的

会返回0

  byte red = Serial2.readBytes(buf,2);
  if(red>0)
  {

以下是“良好数据”案例SvAdd为我提供了发件人地址,FCode给出了发送的邮件类型(有8种类型的邮件,但我们只使用类型3和6)

    valid=true;
    byte SvAdd = buf[0];
    byte FCode = buf[1];
    int Read;
    byte registerL;
    switch (FCode)
    {
      case 3:

案例3(只读)的数据如下表所示: Case 3 Data

        Serial2.readBytes(buf,1);
        registerL = buf[0];
        for (byte i=(registerL/2); i>0 ; i--)
        {
          Serial2.readBytes(buf,2);
          Read = buf[1] | buf[0] << 8;
        }

目前,registerL 应该始终为2但是我添加了循环以防万一

        value=Read;
        break;
      case 6:

案例6(写入然后读取)的数据如下表所示: case 6 Write -> read

        Serial2.readBytes(buf,2);
        Read = buf[1] | buf[0] << 8;
        Serial2.readBytes(buf,2);
        Read = buf[1] | buf[0] << 8;
        value=Read;

我知道地址所以我读过它并且只查看数据位以验证是否写入了正确的函数

        break; 
    }

从函数中获取最后两个CRC字节(清除缓冲区)

    Serial2.readBytes(buf,2);
    int CRC = buf[1] | buf[0] << 8;
    if (echo)
    {
      Serial.println(SvAdd);
      Serial.println(FCode);
      switch (FCode)
      {
        case 3:
          Serial.println(registerL);
          Serial.println(Read);   //Last Value read
          break;
        case 6:
          Serial.println(Read);   //Value
          break; 
      }
      Serial.println(CRC);
    }
    return valid;
  }

red=0

的情况就是这样
  else
  {
    valid=false;   
    Serial.println("timeout");
    return valid;
  }
}

编辑(连续代码)

bool SR(bool echo, int&value)
{ 
  bool valid;
  byte buf [2];
  byte red = Serial2.readBytes(buf,2);
  if(red>0)
  {
    valid=true;
    byte SvAdd = buf[0];
    byte FCode = buf[1];
    int Read;
    byte registerL;
    switch (FCode)
    {
      case 3:
        Serial2.readBytes(buf,1);
        registerL = buf[0];
        for (byte i=(registerL/2); i>0 ; i--)
        {
          Serial2.readBytes(buf,2);
          Read = buf[1] | buf[0] << 8;
        }
        value=Read;
        break;
      case 6:
        Serial2.readBytes(buf,2);
        Read = buf[1] | buf[0] << 8;
        Serial2.readBytes(buf,2);
        Read = buf[1] | buf[0] << 8;
        value=Read;
        break; 
    }
    Serial2.readBytes(buf,2);
    int CRC = buf[1] | buf[0] << 8;
    if (echo)
    {
      Serial.println(SvAdd);
      Serial.println(FCode);
      switch (FCode)
      {
        case 3:
          Serial.println(registerL);
          Serial.println(Read);   //Last Value read
          break;
        case 6:
          Serial.println(Read);   //Value
          break; 
      }
      Serial.println(CRC);
    }
    return valid;
  }
  else
  {
    valid=false;   
    Serial.println("timeout");
    return valid;
  }
}

1 个答案:

答案 0 :(得分:1)

我看到的一件事是Read被定义为int,即签名为int。我想知道你是否会得到更好的结果,因为如果你把它定义为unsigned int,你就是通过位移来创建它。如果您将1转换为该MSB位置,则突然(作为int Read为负数。

下一步:

Read = buf[1] | buf[0] << 8;
Serial2.readBytes(buf,2);
Read = buf[1] | buf[0] << 8;
value=Read;

你意识到Read被连续两次分配,对吧?所以它只保留最后一个值。如果您想丢弃传输的地址,那也没关系。但它看起来并不像你这样:

Serial.println(Read);   //Addr
Serial.println(Read);   //Value

Read不是地址和价值。

我建议你先看看这两个鱼腥物品。我现在无法运行您的代码,但仔细查看这些项目可能会解释您的问题。

最后,如果要传入指针,函数调用本身应该是:

bool SR(bool echo, unsigned int * value)

但最重要的是,如果你每隔一段时间“超时”,那是因为red不是&gt; 0,上面的readBytes语句不起作用。