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,是否有“故障安全”超时代码再次发送命令?

工作代码编辑:

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
      }
 }
4

1 回答 1

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())这里有一条线。我不能确定,但​​这对我来说看起来不正确,它可能会搞砸你。尝试删除该块并在事件中进行读取。让我知道你是怎么做出来的。

我希望这有帮助。

于 2012-06-09T07:08:35.637 回答