Serial temp data read?

I'm using an arduino with an XBEE to poll a temperature monitor. I can see the monitor being polled and on a seperate screen I can see that the monitor is responding back with the current temperature with a 0.1 degree resolution.

My question is how would I take the incoming serial temp data and turn it into "temp = " for use in the rest of the sketch. It would have to recognize both + and - temperatures.

For instance right now the monitor is responding with 77.8 how would I process that incoming stream of data to set it up as temp=

Thanks for any assistance you can provide.

My question is how would I take the incoming serial temp data and turn it into "temp = " for use in the rest of the sketch. It would have to recognize both + and - temperatures.

How would the string "temp = 77.6" be useful?

If it was, for some strange reason, we'd need to see your code that collects the serial data.

Assuming the stream of characters always has a digit after the decimal point:

float Temperature(String temperature)
    {
    bool negative = false;
    int temp = 0;

    for (int i=0; i< temperature.length(); i++)
        {
        char c = temperature[i];
        if (c == '-')
               negative = true;
        if (c >= '0' && c <= '9')
            temp = temp * 10 + (c - '0');
        }

   if (negative)
       temp *= -1;

   return temp/10.0;
   }

Paul,
I apologize..I didn't mean a string "temp=77.6". I just meant that I somehow need to read the incoming serial data and make temp equal to that serial feed.

incoming data would be + or - temp i.e. 77.8

I need temp to equal that number. I just don't understand how to read each number from the serial port and put it together.

I just don't understand how to read each number from the serial port and put it together.

There are two parts of this. First, you need to read all the data, and store it in an array of characters. How will you know when you have read all the characters?

Once you have a complete packet, you can use the atof() function to convert it to a float.

For the first part I beleive you can state:

while (Serial.available() > 0) \something actually in the receive buffer
{
temp = Serial.read()
}

I know this isn't completely right, but I believe by stating the first line it will know when all the data has been read out of the receive buffer. correct?

but I believe by stating the first line it will know when all the data has been read out of the receive buffer. correct?

Yes, but that doesn’t tell you anything. You can read faster than I type. If you were reading over my shoulder you would have read everything I typed long before I get to the period at the end of a sentence.

You need to figure out what represents the end of a packet from your sender.

7.677.777.877.877.877.8
is pretty hard to make sense of. Is that what your device is sending? Is there some separation between values, other than time?

every 15 seconds, the arduino does a serial.print("atn") "atn" is the serial call that the temperature device needs to transmit the temperature out the serial port. The response is immediate, but there is no starting or ending characters before or after the data. There may possibly be a carriage return at the end because when I view it on hyperterminal it does move to the next line after the temperature data is received.

vogel1230:
every 15 seconds, the arduino does a serial.print("atn") "atn" is the serial call that the temperature device needs to transmit the temperature out the serial port. The response is immediate, but there is no starting or ending characters before or after the data. There may possibly be a carriage return at the end because when I view it on hyperterminal it does move to the next line after the temperature data is received.

If the gizmo only sends data when requested, then it can be assumed that the data received is what is desired. A simple delay in the data capture loop may be all you need to capture the data and then do what is needed.

The gizmo only sends one response for one query and the data shows up in less than a second. So yes, we could probably just have the collection of the incoming data stop after a short period of time and I could play with that length of time to ensure all the data was collected.

So how should I start to read that incoming data and put it all together?

Below is a simple data capture code based on a delay between the data strings being sent. Bottom is a data capture method based on a delimiter at the end of the data string.

// zoomkat 7-30-11 serial I/O string test
// type a string in serial monitor. then send or enter
// for IDE 0019 and later

String readString;

void setup() {
  Serial.begin(9600);
  Serial.println("serial test 0021"); // so I can keep track of what is loaded
}

void loop() {

  while (Serial.available()) {
    delay(2);  //delay to allow byte to arrive in input buffer
    char c = Serial.read();
    readString += c;
  }

  if (readString.length() >0) {
    Serial.println(readString);

    readString="";
  } 
}
/*
Example of processing incoming serial data without blocking.

Author: Nick Gammon
Date:   13 November 2011

Released for public use.
*/

void setup()
{
  Serial.begin(9600);
}


const unsigned int MAX_INPUT = 20;
char input_line [MAX_INPUT];
unsigned int input_pos = 0;

void loop()
{

  if (Serial.available () > 0) 
    {
    char inByte = Serial.read ();

    switch (inByte)
      {

      case '\n':   // end of text
        input_line [input_pos] = 0;  // terminating null byte
        
        // terminator reached! process input_line here ...
        Serial.println (input_line);
  
        // reset buffer for next time
        input_pos = 0;  
        break;
  
      case '\r':   // discard carriage return
        break;
  
      default:
        // keep adding if not full ... allow for terminating null byte
        if (input_pos < (MAX_INPUT - 1))
          input_line [input_pos++] = inByte;
        break;

      }  // end of switch

  }  // end of incoming data

  // do other stuff here like testing digital input (button presses) ...

}  // end of loop

So based on the first one could I modify to do the following....

Serial.println("atn"); //query the temp gizmo for current temperature reading
delay(500); //allow time for unit to receive the transmission and process
while (Serial.available()) {
    delay(500);  //delay to allow temp information to arrive in input buffer
    char c = Serial.read();
    readString += c;
  }

  if (readString.length() >0) {
    temp = readString;
  }
while (Serial.available()) {
    delay(500);  //delay to allow temp information to arrive in input buffer
    char c = Serial.read();
    readString += c;
  }

That's going to delay for half a second per character. Even at 300 baud, that's far too long.

  if (readString.length() >0) {
    temp = readString;
  }

What type is temp?

delay(500);  //delay to allow temp information to arrive in

Just go back to the origional delay(2); as that is usually adequate to not out run the filling of the input buffer. A delay(100); in the initial delay after the data request may be all the delay in the code that is actually needed for your particular setup.

OK, switch delay back to (2). got it.

what type is temp?
-temp is going to be short for temperature and will need to be a float so that it can represent positive and negative numbers.

So need to take the readString information and make temp, which needs to be a float, equal to the data in readString.

So need to take the readString information and make temp, which needs to be a float, equal to the data in readString.

Below might be one approach, but there may be shorter methods.

Serial.println(readstring);  //so you can see the captured string
char carray[readstring.length() + 1]; //determine size of the array
readstring.toCharArray(carray, sizeof(carray)); //put readStringinto an array
float f = atof(carray); //convert the array into a float