2013-07-08 34 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; 
    } 
    } 
} 
相關問題