2012-06-08 64 views
0
String cmdData; //Store the complete command on one line to send to sensor board. 

String phResponse; //Store the ph sensor response. 

boolean startOfLine = false; 
boolean endOfLine = false; 
boolean stringComplete = false; 

void setup() 
{ 
    Serial.begin(38400); 
    Serial3.begin(38400); 

    pinMode(2, OUTPUT); //used for temperature probe 
} 

void loop() 
{ 
    if (stringComplete) 
    { 
    Serial.println("Stored Response: " + phResponse); 

    phResponse = ""; //empty phResponse variable to get ready for the next response 

    stringComplete = false; 
    } 
} 

void serialEvent() 
{ 
    while (Serial.available()) 
    { 
    char cmd = (char)Serial.read(); 

    if (cmd == '{') 
    { 
     startOfLine = true; 
    } 

    if (cmd == '}') 
    { 
     endOfLine = true; 
    } 

    if (startOfLine && cmd != '{' && cmd != '}') 
    { 
     cmdData += cmd; 
    } 

    if (startOfLine && endOfLine) 
    { 
     startOfLine = false; 
     endOfLine = false; 

     cmdData.toLowerCase(); //convert cmdData value to lowercase for sanity reasons 

     if (cmdData == "ph") 
     { 
     delay(500); 

     ph(); 
     } 

     if (cmdData == "phatc") 
     { 
     delay(500); 

     phATC(); 
     } 

     cmdData = ""; //empty cmdData variable to get ready for the next command 
    } 
    } 
} 

void serialEvent3() 
{ 
    while(Serial3.available()) 
    { 
    char cmd3 = (char)Serial3.read(); 

    phResponse += String(cmd3); 

    if (cmd3 == '\r') 
    { 
     stringComplete = true; 
     Serial.println("Carriage Command Found!"); 
    } 
    } 
} 

float getTemp(char tempType) 
{ 
    float v_out;   //voltage output from temp sensor 
    float temp;   //the final temperature is stored here (this is only for code clarity) 
    float tempInCelcius; //stores temperature in C 
    float tempInFarenheit; //store temperature in F 

    digitalWrite(A0, LOW); //set pull-up on analog pin 
    digitalWrite(2, HIGH); //set pin 2 high, this will turn on temp sensor 
    delay(2);    //wait 1 ms for temp to stabilize 

    v_out = analogRead(0); //read the input pin 

    digitalWrite(2, LOW); //set pin 2 low, this will turn off temp sensor 

    v_out*=.0048;          //convert ADC points to volts (we are using .0048 because this device is running at 5 volts) 
    v_out*=1000;           //convert volts to millivolts 

    tempInCelcius = 0.0512 * v_out -20.5128;    //the equation from millivolts to temperature 
    tempInFarenheit = (tempInCelcius * 9.0)/ 5.0 + 32.0; // Convert Celcius to Fahrenheit 

    if (tempType == 'c') 
    { 
    return tempInCelcius; //return temp in celcius 
    } 
    else if (tempType == 'f') 
    { 
    return tempInFarenheit; //return temp in Farenheit 
    } 
} 

void ph() 
{ 
    Serial.println("Calculating PH sensor value in 3 Seconds"); 

    delay(3000); 

    Serial3.print("r\r"); 
} 

void phATC() 
{ 
    Serial.println("PH Auto Temperature Calibration will start in 3 Seconds"); 
    delay(3000); 

    float temp = getTemp('c'); 
    char tempAr[10]; 
    String tempAsString; 
    String tempData; 

    dtostrf(temp,1,2,tempAr); 
    tempAsString = String(tempAr); 

    tempData = tempAsString + '\r'; 
    Serial3.print(tempData); 
} 

是否有人可以解釋爲什麼serialEvent3()後的第二個,有時候觸發命令發送到傳感器板第三次。一旦serialEvent3()最終觸發連續的命令工作流利。 serialEvent()似乎按預期工作。我試圖重新安排功能而沒有成功。如果serialEvent3沒有被觸發,是否有'fail safe'超時代碼來再次發送命令?的Arduino兆:無效serialEvent3(){}並不總是觸發(是嗎?)

工作代碼編輯:

String cmdData; //Store the complete command on one line to send to sensor board. 

String phResponse; //Store the ph sensor response. 

boolean startOfLine = false; 
boolean endOfLine = false; 
boolean stringComplete = false; 

boolean s3Trigger = false; 

void setup() 
{ 
    Serial3.begin(38400); 

    Serial.begin(38400); 
} 

void serialEvent() 
{ 
    while (Serial.available()) 
    { 
    char cmd = (char)Serial.read(); 

    if (cmd == '{') 
    { 
     startOfLine = true; 
    } 

    if (cmd == '}') 
    { 
     endOfLine = true; 
    } 

    if (startOfLine && cmd != '{' && cmd != '}') 
    { 
     cmdData += cmd; 
     //Serial.println(cmdData); 
    } 
    } 
} 

void serialEvent3() 
{ 
    while(Serial3.available()) 
    { 
    char cmd3 = (char)Serial3.read(); 

    phResponse += String(cmd3); 

    if (cmd3 == '\r') //if Carriage Return has been found then... 
    { 
     stringComplete = true; 
    } 
    } 
} 

void loop() 
{ 
    if (startOfLine && endOfLine) //both startOfLine and endOfLine must be true to run the command... 
    { 
    startOfLine = false; 
    endOfLine = false; 

    s3Trigger = true; //set the s3Trigger boolean to true to check if data on Serial3.available() is available. 

    runCommand(); 
    } 

    if (stringComplete) 
    { 
    Serial.println("Stored Response: " + phResponse); //print stored response from ph sensor. 

    phResponse = ""; //empty phResponse variable to get ready for the next response 
    cmdData = ""; //empty phResponse variable to get ready for the next command 

    stringComplete = false; //set stringComplete to false 
    s3Trigger = false; //set s3Trigger to false so it doesn't continuously loop. 
    } 

    if (s3Trigger) //if true then continue 
    { 
    delay(1000); //delay to make sure the Serial3 buffer has all the data 

    if (!Serial3.available()) //if Serial3 available then execute the runCommand() function 
    { 
     //Serial.println("!Serial3.available()"); 
     runCommand(); 
    } 
    else 
    { 
     s3Trigger = false; //set s3Trigger to false so it doesn't continuously loop. 
    } 
    } 
} 

void runCommand() 
{ 
    cmdData.toLowerCase(); //convert cmdData value to lowercase for sanity reasons 

    if (cmdData == "ph") 
    { 
    ph(); 
    } 
} 

void ph() 
{ 
    Serial.println("Calculating PH sensor value in 3 Seconds"); 

    delay(3000); 

    Serial3.print("r\r"); 
} 

工作新代碼,而不必兩次發送命令:

/* 
This software was made to demonstrate how to quickly get your Atlas Scientific product running on the Arduino platform. 
An Arduino MEGA 2560 board was used to test this code. 
This code was written in the Arudino 1.0 IDE 
Modify the code to fit your system. 
**Type in a command in the serial monitor and the Atlas Scientific product will respond.** 
**The data from the Atlas Scientific product will come out on the serial monitor.** 
Code efficacy was NOT considered, this is a demo only. 
The TX3 line goes to the RX pin of your product. 
The RX3 line goes to the TX pin of your product. 
Make sure you also connect to power and GND pins to power and a common ground. 
Open TOOLS > serial monitor, set the serial monitor to the correct serial port and set the baud rate to 38400. 
Remember, select carriage return from the drop down menu next to the baud rate selection; not "both NL & CR". 
*/ 



String inputstring = "";              //a string to hold incoming data from the PC 
String sensorstring = "";              //a string to hold the data from the Atlas Scientific product 
boolean input_stringcomplete = false;           //have we received all the data from the PC 
boolean sensor_stringcomplete = false;           //have we received all the data from the Atlas Scientific product 

    #include <SoftwareSerial.h> 

    SoftwareSerial mySerial(10, 11); // RX, TX 

    void setup(){ //set up the hardware 
    //set up the hardware 
    Serial.begin(38400);              //set baud rate for the hardware serial port_0 to 38400 
    mySerial.begin(38400); 

    inputstring.reserve(5);             //set aside some bytes for receiving data from the PC 
    sensorstring.reserve(30);             //set aside some bytes for receiving data from Atlas Scientific product 

    pinMode(12, OUTPUT); 

    digitalWrite(12, HIGH);  // turn on pullup resistors 

    //mySerial.print("i\r"); 
    } 



    void serialEvent() {               //if the hardware serial port_0 receives a char    
       char inchar = (char)Serial.read();        //get the char we just received 
       inputstring += inchar;           //add it to the inputString 
       if(inchar == '\r') {input_stringcomplete = true;}    //if the incoming character is a <CR>, set the flag 
       } 



void loop(){                 //here we go.... 

    while(mySerial.available()) 
    { 
       char inchar = (char)mySerial.read();        //get the char we just received 
       sensorstring += inchar;           //add it to the inputString 
       if(inchar == '\r') {sensor_stringcomplete = true;}    //if the incoming character is a <CR>, set the flag 

      //Serial.print(inchar); 
    } 

    if (input_stringcomplete){ //if a string from the PC has been recived in its entierty 
     //Serial.print(inputstring); 
     mySerial.print(inputstring);            //send that string to the Atlas Scientific product 
     inputstring = "";              //clear the string: 
     input_stringcomplete = false;           //reset the flage used to tell if we have recived a completed string from the PC 
     } 

if (sensor_stringcomplete){             //if a string from the Atlas Scientific product has been recived in its entierty 
     Serial.println(sensorstring);           //send that string to to the PC's serial monitor 
     sensorstring = "";              //clear the string: 
     sensor_stringcomplete = false;           //reset the flage used to tell if we have recived a completed string from the Atlas Scientific product 
     } 
} 

回答

0

一件事我注意到(而不是串行讀取問題的原因)。在微處理器中浮點數學是昂貴的。這可能是值得的,同時這三個行結合:

v_out*=.0048; 
v_out*=1000; 
tempInCelcius = 0.0512 * v_out -20.5128; 

到:

tempInCelcius = v_out * 0.24576 -20.2128; 

我也動tempInFarenheit = (tempInCelcius * 9.0)/ 5.0 + 32.0;右轉入return語句,所以如果需要的計算僅完成。鼓勵在PC上進行編程,但是使用微處理器時,我傾向於壓縮代碼並插入很多評論。

編輯:

我看了一下對傳感器的示例代碼,我想我有事情你可以試試。你在這裏有一個while (Serial.available())行。我不能確定,但​​這對我來說並不合適,這可能會讓你感到困擾。嘗試刪除該塊,然後在活動中進行閱讀。讓我知道你是如何做出的。

我希望這會有所幫助。

+0

我加了:delay(5000); while(!Serial3.available()){Serial.println(Serial3.read()); }到if(cmdData ==「ph」)。我現在收到-1作爲打印輸出。這是奇怪的行爲,因爲當ph()函數被觸發時,傳感器板上的燈閃爍。當傳感器板接收命令或發送響應時,它們只會閃爍;它們會在接收和發送串行數據時閃爍兩次。我仍然不明白爲什麼我第二次發送{ph}第二次和第三次得到回覆。鏈接到數據表:http://www.atlas-scientific.com/_files/pH_Circuit_3.0.pdf – dottedquad

+0

我回到製造商的示例代碼,看看我是否有同樣的問題,我是。看起來像Serial3.available即使我使用延遲也沒有得到第一個響應。 – dottedquad

+0

查看數據表後,我編輯了我的答案。試試這個,讓我知道。 – cstrutton

相關問題