2013-07-08 97 views
1

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

  • {open_valve}
  • {CLOSE_VALVE}

当我发送命令,{open_valve}到Arduino,阀门打开罚款,但当我将命令{close_valve}发送给Arduino时,阀门不关闭。草图看起来像下面,

// 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; 
    } 
    } 
} 

回答

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

你的代码不应该编译为粘贴在这里。 checkForCorrectCommand函数没有匹配和不匹配的返回值。你的代码显示你打算为匹配和不匹配的情况清空inputString缓冲区。如果字符串匹配不正确,则希望保持输入缓冲区不变,以便可以运行以下测试用例。

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; 
    } 
+0

感谢您的建议,今天晚些时候我会试一试。 – Chris

+0

jdr5ca当我把else语句放在那里时,阀门不打开也不关闭。我接受了其他声明,现在我至少可以打开阀门。 – Chris

+0

等一下,你的意思是说你原来的代码里没有别的东西?我认为这只是一个粘贴代码的错误。 checkForCorrectCommand()没有书面工作的机会 – jdr5ca

0

jdr5ca的注释非常正确。 checkForCorrectCommand例程需要一个带有单独返回语句的else子句。 Chris设计的解决方案很好。如果它是完整的,只处理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; 
    } 
    } 
} 
相关问题