Perintah string untuk sketsa Arduino berfungsi tetapi tidak juga

Jadi saya memiliki sketsa Arduino yang membaca perintah serial (rangkaian karakter) dan kemudian membuat sketsa tersebut melakukan sesuatu berdasarkan perintah yang diterimanya. Saat ini saya memiliki dua perintah,

  • {buka_katup}
  • {close_valve}

Ketika saya mengirimkan perintah {open_valve} ke Arduino, katup terbuka dengan baik, tetapi katup tidak menutup ketika saya mengirimkan perintah {close_valve} ke Arduino. Sketsanya terlihat seperti berikut,

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

person ipatch    schedule 08.07.2013    source sumber


Jawaban (3)


Kode Anda tidak boleh dikompilasi seperti yang ditempelkan di sini. Fungsi checkForCorrectCommand tidak memiliki nilai kembalian untuk kecocokan dan ketidakcocokan. Kode Anda menunjukkan bahwa Anda bermaksud mengosongkan buffer inputString untuk kasus yang cocok dan tidak cocok. Jika kecocokan string tidak benar, Anda ingin membiarkan buffer input tidak berubah sehingga kasus pengujian berikut dapat dijalankan.

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;
  } 
person jdr5ca    schedule 09.07.2013
comment
terima kasih atas sarannya, saya akan mencobanya nanti hari ini. - person ipatch; 09.07.2013
comment
jdr5ca ketika saya memasukkan pernyataan lain di sana, katup tidak terbuka atau tertutup. Aku mengeluarkan pernyataan lain, dan sekarang setidaknya aku bisa membuka katupnya. - person ipatch; 10.07.2013
comment
tunggu, maksudmu tidak ada yang lain dalam kode aslimu? Saya pikir itu hanya kesalahan saat menempelkan kode. checkForCorrectCommand() tidak memiliki peluang untuk berfungsi seperti yang tertulis - person jdr5ca; 10.07.2013

Jadi saya memodifikasi sketsa saya dengan kode berikut, dan sekarang sepertinya perintah serial diproses sesuai keinginan saya juga.

 // 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());
  }
}
person ipatch    schedule 16.07.2013

Catatan dari jdr5ca cukup benar. Rutinitas checkForCorrectCommand memerlukan klausa else dengan pernyataan return terpisah. Solusi yang dibuat oleh Chris bagus. Jelas lebih baik hanya memproses konten inputString jika sudah selesai dan membuangnya (isi inputString) setelah memeriksa perintah yang valid. Saya ingin menawarkan perubahan kecil pada serialEvent.

Rutinitas serialEvent tidak boleh terus-menerus menambahkan karakter ke string yang sudah lengkap. Sebaliknya, ia harus membiarkannya di buffer untuk membantu membentuk perintah berikutnya. Lihat kode di bawah ini.

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;
    }
  }
} 
person Peter Schaeffer    schedule 10.11.2013