Arduino草图的字符串命令有点工作但不是真的

时间:2013-07-08 23:44:51

标签: c arduino arduino-ide

所以我有一个Arduino草图,它读取串行命令(一串字符)然后让草图根据它收到的命令做一些事情。截至目前,我有两个命令,

  • {open_valve}
  • {CLOSE_VALVE}

当我向Arduino发送命令{open_valve}时,阀门打开正常,但是当我向Arduino发送命令{close_valve}时阀门没有关闭。草图如下所示,

 // flow_A LED
 int led = 4;

 // relay_A
 const int RELAY_A = A0;

 // variables from sketch example
 String inputString = ""; // a string to hold incoming data
 boolean stringComplete = false; // whether the string is complete

 // variables from SO thread
 boolean LED_state = false;
 boolean vavle_open = false;

// flowmeter shit
unsigned long totalCount = 0;
unsigned long previousCount = 0;
int pin = 2;
unsigned long duration;

// storage variable for the timer
unsigned long previousMillis=0;
int interval=1000; //in milliseconds

// counters for each flowmeter
unsigned long countA = 0;

 void setup() {

   Serial.begin(115200); // open serial port, sets data rate to 115200bps
   Serial.println("Power on test");
   inputString.reserve(200);

   pinMode(RELAY_A, OUTPUT);

   // flowmeter shit
   pinMode(pin, INPUT);

}

void open_valve() {

  digitalWrite(RELAY_A, HIGH); // turn RELAY_A on

  // set the boolean value for "vavle_open" to true
  //valve_open = true;
  Serial.println("Valve Open");

}

void close_valve() {
  Serial.println("2");
  digitalWrite(RELAY_A, LOW); // turn RELAY_A off
  //valve_open = false;
  Serial.println("3");
  Serial.println("Vavle Closed");
}

void controlValve(bool open)
{

}

void flow_A_blink() {

  digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
  delay(1000);              // wait for one second
  digitalWrite(led, LOW);   // turn the LED off by making the voltage LOW
  delay(1000);              // wait for a second
}

void flow_A_blink_stop() {

  digitalWrite(led, LOW);
}

void getFlow() {

  duration = pulseIn(pin, HIGH);
  Serial.print(duration);
  Serial.println("");
  delay(200);
}

/*
 * Main program loop, runs over and over repeatedly
 */

void loop() {
  if(checkForCorrectCommand("{open_valve}") == true) {
    open_valve();
    Serial.println("OPENING"); 
    getFlow();   
  }
  else if(checkForCorrectCommand("{close_valve}") == true)
  {
    close_valve();
    Serial.println("CLOSING");
  }
}

bool checkForCorrectCommand(String cmd) {  

    //Serial.println(inputString);
    //Serial.println(cmd);

    if(inputString == cmd) { 
     // reset String variables for serial data commands
     Serial.println("1");
     inputString = "";
     stringComplete = false;
     return true;
      // reset String variables for serial data commands
      inputString = "";
      stringComplete = false;
      return false;
    } 
}

//SerialEvent occurs whenever a new data comes in the
//hardware serial RX.  This routine is run between each
//time loop() runs, so using delay inside loop can delay
//response.  Multiple bytes of data may be available.

void serialEvent() {
  while(Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}

3 个答案:

答案 0 :(得分:0)

您的代码不应该像在此处粘贴一样进行编译。 checkForCorrectCommand函数没有匹配和不匹配的返回值。您的代码显示您打算为匹配和非匹配大小写清空inputString缓冲区。如果字符串匹配不为true,则您希望保持输入缓冲区不变,以便可以运行以下测试用例。

bool checkForCorrectCommand(String cmd) {  

  if(inputString == cmd) { 
    // for match case, the string is consumed from the buffer
    inputString = "";
    stringComplete = false;
    return true;
  } 
  else {
    // for the non-match case, leave the buffer for further Rx or further tests
    return false;
  } 

答案 1 :(得分:0)

所以我使用以下代码修改了草图,现在它似乎也按照我想要的方式处理串行命令。

 // flow_A LED
 int led = 4;

 // relay_A
 const int RELAY_A = A0;

 // variables from sketch example
 String inputString = ""; // a string to hold incoming data
 boolean stringComplete = false; // whether the string is complete

 // variables from SO thread
 boolean LED_state = false;
 boolean vavle_open = false;

// flowmeter shit
unsigned long totalCount = 0;
unsigned long previousCount = 0;
int pin = 2;
unsigned long duration;

// storage variable for the timer
unsigned long previousMillis=0;
int interval=1000; //in milliseconds

// counters for each flowmeter
unsigned long countA = 0;

void setup() {
   // initialize serial
   Serial.begin(9600); // open serial port, sets data rate to 115200bps
   // Serial.println("Power on test - println");
   // line below is for iPhone testing
   // Serial.write("Power on test - write");
   inputString.reserve(200);

   pinMode(RELAY_A, OUTPUT);

   // flowmeter shit
   pinMode(pin, INPUT);

}

void open_valve() {

  digitalWrite(RELAY_A, HIGH); // turn RELAY_A on
  // Serial.println("Valve Open");
  Serial.write("{valve_open}");
}

void close_valve() {
  digitalWrite(RELAY_A, LOW); // turn RELAY_A off
  // Serial.println("Vavle Closed");
  Serial.write("{valve_close}");
}

void flow_A_blink() {

  digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
  delay(1000);              // wait for one second
  digitalWrite(led, LOW);   // turn the LED off by making the voltage LOW
  delay(1000);              // wait for a second
}

void flow_A_blink_stop() {

  digitalWrite(led, LOW);
}

void getFlow() {

  duration = pulseIn(pin, HIGH);
  Serial.print(duration);
  Serial.println("");
  delay(200);
}

/*
 * Main program loop, runs over and over repeatedly
 */

void loop() {

 //print the string when a newline arrives:
 if(stringComplete) {
//    Serial.println(inputString);

    if(inputString.equals("{open_valve}\n")) {
//       Serial.println("opening valve.");
       open_valve();
    }

    if(inputString.equals("{open_valve}")) {
//       Serial.println("opening valve.");
       open_valve();
    }

    if(inputString.equals("{close_valve}\n")) {
//      Serial.println("close vavle.");
      close_valve();
    }

    if(inputString.equals("{close_valve}")) {
//      Serial.println("close vavle.");
      close_valve();
    }

  // clear the string:
  inputString = "";
  stringComplete = false;
  }
}

/*
 SerialEvent occurs whenever a new data comes in the
 hardware serial RX.  This routine is run between each
 time loop() runs, so using delay inside loop can delay
 response.  Multiple bytes of data may be available.
*/

void serialEvent() {
  while(Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    }
    // Serial.println(inputString.length());
  }
}

答案 2 :(得分:0)

jdr5ca的说明非常正确。 checkForCorrectCommand例程需要一个带有单独return语句的else子句。克里斯设计的解决方案很好。显然,只有在完成后才处理inputString的内容并在检查有效命令后丢弃它(inputString的内容)。我想对serialEvent进行一些小改动。

serialEvent例程不应该继续向已经完成的字符串添加字符。相反,它应该将它们留在缓冲区中以帮助形成下一个命令。请参阅下面的代码。

void serialEvent() {
  if (stringComplete)
    return;
  while(Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}