Arduino 1无法正确读取Serial Monitor中的字符串

时间:2015-12-07 20:57:19

标签: arduino serial-port arduino-uno arduino-ide

我在Arduino Uno上遇到串口显示器问题。

基本上我想在串口监视器上写一些命令,读取字符串并根据字符串做一些事情。

问题如下:假设我输入命令' read 4'在串行监视器中,有时字符串被正确读取,有时读取如下:' ead 4',缺少第一个字符。 我甚至在串行监视器的两个读数之间放了一个延迟。有人有解释吗?

为了完整性,我发布了我的代码(基本上它是从EEPROM读/写的:例如'读5'将读取5块EEPROM,'写4 5'将值5写入第4块内存。)

#define MAX_STRING_LENGTH 14
#include <ctype.h>
#include <EEPROM.h>


//The function initializes the string to spaces
void initString(char* mystr, char strLength);

//The function returns true if it is a read operation, false otherwise
boolean isReadEEPROM(char *myStr, char strLength);

//The function returns true if it is a write operation, false otherwise
boolean isWriteEEPROM(char *myStr, char strLength);

//The function returns the EEPROM address from the string
unsigned int findAddress(char *myStr, char strLength);

char findValue(char *myStr, char strLength);

//Check the address range
boolean isAddressOk(unsigned int address);



void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);


}

void loop() {

  char pos = 0; 
  bool newDataFound = false;
  char serialStr[MAX_STRING_LENGTH];
  unsigned int address = 0;
  char val = 0;
  while(Serial.available()){
    val = Serial.read();

  }
  val = 0;
  initString(&serialStr[0], (char) MAX_STRING_LENGTH);
  while(Serial.available() && pos < MAX_STRING_LENGTH){
    serialStr[pos] = Serial.read();
    pos ++;
    newDataFound = true;
    delay(200);
  }
  if (newDataFound){
    Serial.print("New Command found: ");
    Serial.println(serialStr);
    address = 0;
    address = findAddress(&serialStr[0], MAX_STRING_LENGTH);

    if (isReadEEPROM(&serialStr[0], MAX_STRING_LENGTH) && isAddressOk(address)){
      Serial.println("Reading from EEPROM");
      Serial.print("Address is ");
      Serial.println(address);
      val = EEPROM.read(address);
      Serial.print("Value is: ");
      Serial.println( (uint8_t) val );
      Serial.println(" ");

    }
    else if (isWriteEEPROM(&serialStr[0], MAX_STRING_LENGTH) && isAddressOk(address)){
      Serial.println("Writing to EEPROM");
      Serial.print("Address is ");
      Serial.println(address);
      Serial.println(" ");

      val = findValue(&serialStr[0], MAX_STRING_LENGTH);
      EEPROM.write(address, val);

    }
    else{
      if (!isAddressOk(address)){
        Serial.write(address);
        Serial.println("Address out of range");
        Serial.println("");
      }
      Serial.println("Not recognized operation\n");
    }

   delay(2000);
    }
}

void initString(char* mystr, char strLength){
  for(char ii=0; ii<strLength; ii++){
    (*mystr) = ' ';
    mystr++;
  } 
}

//The function returns true if it is a read operation, false otherwise
boolean isReadEEPROM(char *myStr, char strLength){
  //The string should contain first the 'read' operation
  char expected[] = "read";

  int ii =0;

  while (ii<4){
    if ( *(myStr + ii) !=  expected[ii]){
      return false;
      Serial.println("Not a Read Operation\n");
    }
    ii++;
  }
  return true;
  Serial.println("Read Operation");
}

//The function returns true if it is a write operation, false otherwise
boolean isWriteEEPROM(char *myStr, char strLength){
  //The string should contain first the 'read' operation
  char expected[] = "write";
  int ii =0;

  while (ii<5){
    if ( *(myStr + ii) !=  expected[ii]){
      return false;
    }
    ii++;
  }
  return true;
}

//The function returns the EEPROM address from the string
unsigned int findAddress(char *myStr, char strLength){
    unsigned int address;
    char tmpStr[strLength];
    char strAddress[] = "    ";
    int ii = 0;
  while(ii< strLength){
   tmpStr[ii] = *(myStr+ii);
   ii++;
  }
  Serial.print("The address found is: ");
  Serial.println(strAddress);
  ii= 0;

  if (isReadEEPROM(myStr, strLength)){
      while (ii<=4){
          if (isdigit(*(myStr + 5 + ii))){
            strAddress[ii] = *(myStr + 5 + ii);
          }
          else{
            break;
          }
          ii++;
      }
      address = atoi(strAddress);
  }

else if(isWriteEEPROM(myStr, strLength)){
        while (ii<=4){
          if (isdigit(*(myStr + 6 + ii))){
            strAddress[ii] = *(myStr + 6 + ii);
          }
          else{
            break;
          }
          ii++;
        }
        address = atoi(strAddress);
}

else{
  address = 0;
  //Serial.println("Address not available in function 'findAddress'");
}
 return address;
}

//The function returns the value to be written to the EEPROM from the string
char findValue(char *myStr, char strLength){
  char val;
  char tmpStr[strLength];
  char strVal[] = "   ";
  int ii, idx = 0;
  while(ii< strLength){
   tmpStr[ii] = *(myStr+ii);
   ii++;
  }
  ii= 0;
 // first found the first digits corresponding to the address
  while (ii<=4){
      if (isdigit(*(myStr + 6 + ii))){
        ;//strAddress[ii] = *(myStr + 6 + ii);
      }
      else{
        ii++;
        break;
      }
      ii++;
  }
  // now find the value
  while (ii<=4+3){
      Serial.println(*(myStr + 6 + ii));

      if (isdigit(*(myStr + 6 + ii))){
        strVal[idx] = *(myStr + 6 + ii);
      }
      else{
        break;
      }
      ii++;
      idx++;
  }          
 Serial.print("original string: ");
 Serial.println(tmpStr);
 Serial.print("Value found: ");
 Serial.println(strVal);
 val = (char)atoi(strVal);
 return val;
}

boolean isAddressOk(unsigned int address){
  if (address < 1024 && address >= 0){
    return true;
  }
  else{
    return false;
  }
}

1 个答案:

答案 0 :(得分:2)

此片段:

char val=0;
while(Serial.available()){
  val = Serial.read();
}
val = 0;

只消耗可能留在输入缓冲区中的任何字符。你也可以这样做:

while (Serial.avaialble())
  Serial.read();

下一个while循环不等待整个命令。有时候,它会得到'r',然后就不会及时得到'ead ......'。它们将在下次loop执行时出现,因此看起来“r”缺失。它刚刚在之前的loop消费。

通过USB(从串行监视器窗口)发送的内容可能会有奇怪的延迟。

要收集完整行,您应该保存字符,直到收到'\ n':

for (;;) {
  if (Serial.available()) {
    char c = Serial.read();
    if (c == '\n')
      break;
    if (pos < MAX_LINE_LENGTH) {
      serialStr[pos] = c;
      pos ++;
    }
    newDataFound = true;
  }
}

delay调用是完全没必要的,因为for循环等待直到收到'\ n'字符(确保在串行监视器下拉菜单中'新行'或' NL&amp; CR'都被选中)。然后你知道你已经阅读了该行中的所有字符。