Inaccurate result when combining LM35 + XBee

I am currently doing a project reading Body temperature and pulse sensor that will sent the result wirelessly through XBee.

I started by trying each components separately and everything works fine.

Problem:

Inaccurate result when I combine the XBee and LM35 sensor.

The sensor keep giving the same result. Here’s the sketch output.

    LM35 Thermometer
    Analog in reading: 1023 - Calculated Temp: 109.8
    Analog in reading: 1023 - Calculated Temp: 109.8
    Analog in reading: 1023 - Calculated Temp: 109.8
    Analog in reading: 1023 - Calculated Temp: 109.8

Here’s the code I used:

    #include <SoftwareSerial.h>

    SoftwareSerial xbee(2, 3); //RX, TX

    int potPin = 0;
    float temperature = 0;
    void setup()
    {
      Serial.begin(9600);
      Serial.println("LM35 Thermometer ");
      analogReference(INTERNAL);
      xbee.begin(9600);
    }
    void printTenths(int value) {
      // prints a value of 123 as 12.3
      Serial.print(value / 10);
      xbee.print(value/10);
      Serial.print(".");
      xbee.print(".");
      Serial.println(value % 10);
      xbee.print(value % 10);
    }
    void loop() {
      int span = 20;
      int aRead = 0;
      for (int i = 0; i < span; i++) {
        aRead = aRead+analogRead(potPin);
      }
        aRead = aRead / 20;
        temperature = ((100*1.1*aRead)/1024)*10;
        // convert voltage to temperature
        Serial.print("Analog in reading: ");
        Serial.print(long(aRead));
        // print temperature value on serial monitor
        Serial.print(" - Calculated Temp: ");
        xbee.print(" - Calculated Temp: ");
        printTenths(long(temperature));
       
        delay(500);
    }

I am very sure that before combining it with XBee everything works just fine.

Can anyone explain to me what’s the problem here?

Do it need any voltage adjustment or something?

Which XBee module? Exact model.

How is the LM35 connected to the XBee?

Have you tried substitute a pot for the LM35 for testing?

Code is running on what processor?

“started by trying each components separately” Exactly which components and how were they tested?

I see a few things I would do differently in your code but I don’t think they are the source(s) of your error. At worst I think the way you handle integer and FP math adds a tenth or so of a degree of error in the reported temp. I do wonder if you aren’t getting an error in the ADC process due to pickup on the pin prior to it being connected internally to the ADC. The thing to do is read the analog pin to get it switched to the ADC, then toss out that 1’st reading. Wait a time for the internal capacitances to charge to the proper, connected, value and then read it again. I’d also put a delay in the read loop so you get truly independant values for the readings. Your code “waits” only as long as it takes to go around the loop, perhaps 130 usec. I’m not sure those will average well. Given you’re waiting 500 msec before reporting the temps, adding a small delay btw the ADC readings won’t affect the that timing.

But even given all the above it looks like your averaged ADC reading is pegged at full scale. I’d recheck your wiring just to be sure pin A0 is still actually attached to the LM35. I’d also unplug the XBee from the circuit, changing nothing else, and see what the printouts show. Can I assume correctly that both the XBee and serial monitor prints agree ? Are you using an XBee on a shield or ???

So here’s my version of your code. I didn’t have a pot handy to twiddle to simulate the LM35 so I just stored what I thought were expected values and used them instead of reading the ADC. You can see that commented out in the code below. I played games with the ints and floats just to see if that wasn’t a problem. As said above, it’s not a big problem but you can play with the code below and change those declarations as well to see for yourself. You can see where I’ve used “span” instead of 20 and changed the print to send only 1 significant digit of the FP “temperature”. Look it over and keep whatever you like.

#include <SoftwareSerial.h>

SoftwareSerial xbee(2, 3); //RX, TX

int potPin = 0;
float temperature = 0;
int span = 20;
int aRead = 0;
int simRead [] =
{
250,
150,
199,
201,
198,
202,
220,
180,
207,
193,
201,
201,
201,
201,
201,
202,
202,
202,
202,
202
};

void setup()
{
  Serial.begin(9600);
  Serial.println("LM35 Thermometer ");
  analogReference(INTERNAL);
  xbee.begin(9600);
}

void loop() {
  aRead = analogRead(potPin);
  delay(1);
  aRead = 0;
  for (int i = 0; i < span; i++) {
    aRead = aRead + analogRead(potPin);
    //aRead = aRead + simRead[i];
    delay(1);
  }
  //aRead = aRead / 20;
  temperature = ((100*1.1*aRead/span)/1024);
  // convert voltage to temperature
  Serial.print("Analog in reading: ");
  Serial.print(aRead/span);
  // print temperature value on serial monitor
  Serial.print(" - Calculated Temp: ");
  xbee.print(" - Calculated Temp: ");
  Serial.println(temperature,1);
  xbee.println(temperature,1);
  
  delay(479);
}

waltr:
How is the LM35 connected to the XBee?

I inferred from the code that the LM35 is connected to the Arduino and digitized by it’s ADC. That value is then sent via XBee to another XBee + receiving station of some sort (Explorer).

waltr:
Which XBee module? Exact model.

How is the LM35 connected to the XBee?

Have you tried substitute a pot for the LM35 for testing?

Code is running on what processor?

“started by trying each components separately” Exactly which components and how were they tested?

The code is running on Windows 7 64-bit.

So first I try the XBee from the arduino UNO sending data to PC wirelessly, result is OK.

Then I try plugging the LM35 directly to the arduino UNO board and using this code:

int potPin = 0;
float temperature = 0;
void setup()
{
  Serial.begin(9600);
  Serial.println("LM35 Thermometer ");
  analogReference(INTERNAL);
}
void printTenths(int value) {
  // prints a value of 123 as 12.3
  Serial.print(value / 10);
  Serial.print(".");
  Serial.println(value % 10);
}
void loop() {
  int span = 20;
  int aRead = 0;
  for (int i = 0; i < span; i++) {
    aRead = aRead+analogRead(potPin);
  }
    aRead = aRead / 20;
    temperature = ((100*1.1*aRead)/1024)*10;
    // convert voltage to temperature
    Serial.print("Analog in reading: ");
    Serial.print(long(aRead));
    // print temperature value on serial monitor
    Serial.print(" - Calculated Temp: ");
    printTenths(long(temperature));
    
    delay(500);
}

The result is OK.

Problem comes when I combine both of them.

If you have a voltmeter, check the basics. Verify 5V on the breadboard on the LM35 pins. Then unplug the yellow wire from the shield and measure it’s voltage. It should be around 250 mV. After that plug the yellow lead back in and check that the 250 mV is on the A0 pin of the Uno from it’s underneath side, if you can. I just want to be sure the shield is making good contact(s) with the Uno.

Mee_n_Mac:
If you have a voltmeter, check the basics. Verify 5V on the breadboard on the LM35 pins. Then unplug the yellow wire from the shield and measure it’s voltage. It should be around 250 mV. After that plug the yellow lead back in and check that the 250 mV is on the A0 pin of the Uno from it’s underneath side, if you can. I just want to be sure the shield is making good contact(s) with the Uno.

Just edit the temperature calculation instead of multiplying with 1.1 volt, I changed it into 5.0 volt. Problem solved! Thank you for your help :smiley:

Well that’s good, if a little odd. So long as it all works I guess !