Xbee ADC value not correctly converted ....help !!!!

Hello,

I m a student and I m working on a temperature sensor network with Xbee modules. I m using Xbee Pro Serie 1 modules, and I’m getting my datas transmitted correctly but not converted correctly …

I’m using a LM35DZ temp sensor, which is an analog sensor without offset, and a scale of 10 mV per degree . This is a celsius sensor, so in my output sensor pin I have 0.31 V, which means 31°C , everything’s good . But my problem is here . I have a data value at 85 (0x54), and converted, I have 98.53, and divided by 10, I have 9.85 following the formula . I m using a zigbee pro serie 1 … and I have read this :

http://www.digi.com/wiki/developer/index.php/Voltage_Readings_in_XBee_Module

but I still have the same problem … Can you help me please …

here is my code :

#define NUM_ANALOG_SAMPLES 5         // On définit la variable NUM_ANALOG_SAMPLES égale à 5
int packet[32];
int analogSamples[NUM_ANALOG_SAMPLES];

//=================== SETUP =================================
void setup() {
  Serial.begin(9600);
  delay(1000);
  Serial.print("Starting.........."); 
  Serial.println(); 
}

//==================== LOOP =================================
void loop() {


  readPacket();
}

//==================== podprogramy XBEE ======================
void readPacket() {                        // fonction readPacket lit les paquets de données transmis
  if (Serial.available() > 0) {
    int b = Serial.read();
    if (b == 0x7E) {
      packet[0] = b;                         // On lit les trois premiers paquets puis on définit la taille des données transmises   
      packet[1] = readByte();
      packet[2] = readByte();
      int dataLength = (packet[1] << 8) | packet[2];  // Ici grace à datalength qui correspond a la concatenation du paquet 1 et 2

      for(int i=1;i<=dataLength;i++) {
        packet[2+i] = readByte();               // Ici on lit la suite des paquets reçus
      }
      int apiID = packet[3];                // On définit l ID API avec le paquet 3 .
      int moduleID;
      //0x83 signifie que c'est une réception en mode d'adressage 16 bits
      if (apiID == 0x83) {
        //int analogSampleIndex = 19;
        moduleID = (packet[4] << 8) | packet[5];
        int SgnlPwr = packet[6];
        int SampleNumber = packet[8];
        int i;
        
        if (SampleNumber >= 1)  {

          for (i=1;i<=SampleNumber;i++) {
            analogSamples[i] = (packet[10+i] << 8) | packet[11+i];
          }
        }	
        else {
          analogSamples[i]=-1;
        }
      }

      int reading = analogSamples[1];  // On lit la valeur de la broche  19

      // On converti la valeur lue  en millivolts
      float v = ((float)reading / 1023.0) * 1200.0;    //la valeur renvoyée ( 2 bits)  dans le paquet représente une valeur entiere sur une échelle de 0 à 1023 (0x0 - 0x3FF)
      //  le maximum de tension sur les broches analogiques est de 1200 mV
      // convert to Celcius.  10mv per Celcius degree
      float c = v / 10.0;
     	  
	
      printPacket(dataLength+4);
      Serial.print("data: ");
      Serial.println(reading);
      Serial.print("valeur convertie : ");
      Serial.println(v);
      Serial.print("Module ");
      Serial.println(moduleID);
      Serial.print("Temperature: ");
      Serial.println(c);
      Serial.println();
      Serial.println();
      
    }
  }
}

void printPacket(int l) {
  for(int i=0;i < l;i++) {
    if (packet[i] < 0xF) {
      // print leading zero for single digit values
      Serial.print(0);
    }
    Serial.print(packet[i], HEX);
    Serial.print(" ");
  }
  Serial.println("");
}

int readByte() {         // prog pour lire les données sur le port série. il renvoie la valeur serial.read
  while (true) {						// si le port série est dispo et a une information
    if (Serial.available() > 0) {
      return Serial.read();
    }
  }
}

and here my results :

7E 00 0A 83 00 03 58 00 01 04 00 00 53 00 
data: 83
valeur convertie : 97.36
Module 3
Temperature: 9.74


7E 00 0A 83 00 04 50 00 01 04 00 00 54 00 
data: 84
valeur convertie : 98.53
Module 4
Temperature: 9.85


7E 00 0A 83 00 03 57 00 01 04 00 00 53 00 
data: 83
valeur convertie : 97.36
Module 3
Temperature: 9.74


7E 00 0A 83 00 04 51 00 01 04 00 00 54 00 
data: 84
valeur convertie : 98.53
Module 4
Temperature: 9.85

From your link:

Read the Vcc/power pin level directly with the AT command V%. The actual interpretation of the 16-bit value returned may vary based upon the technology, but for example in the XB24-ZB a reading of 0x0900 (2304) represents 2700mV. The two formulas used in the gateway are:

set_value = ((1024 * user_mv_desired) + 600) / 1200 read_mv = ((1200 * get_value) + 512) / 1024

(The +600/+512 handles the truncation due to integer division)

From your code:

float v = ((float)reading / 1023.0) * 1200.0;

That does not look like either of the equations they show.

This formula is one I've found in an older post that you also comment :

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1264655063

I thought ADC Zigbee Pro Serie 1 input worked like Serie 2 but it don't seems to be .

so after, I tried with the Digi formula, but I have the sames results ....

Why does I have a value like 90 ? Is the scale is the same here ( 0x00 - 0x3FF for 1200 mV) ?

I really don't understand .... I even thought that the temperature was displayed in Farenheit ....but the sensor is clearly a Celsius sensor ....

Isn't the ADC voltage of series 1 XBees much higher than 1.2 volts? I personally don't use them, but I thought ADC value might be like Vcc (3V3)? It's just a guess you may have to look up the ADC (max.) input voltage to get it clear.

markbee

I’ve take a look on the datasheet and I saw :

MIN MAX
Vain ( analog input voltage ) : 2.08 Vddad

and the datasheet says Vddad is connected to Vcc , so to + 3.3V . I probably made a mistake but I substract 3.3 to 2.08 ( nearly 2.1…) so 3.3 - 2.1 = 1.2 V … That’s why I thought it also was 1200 mV .

So if I understand clearly, it’s 0 - 3.3V max for the range of the ADC input …?

here is the datasheet for my Xbee Pro Serie 1 : http://ftp1.digi.com/support/documentation/90000982_B.pdf and it’s on page 8 .

Yes, if Vcc is 3V3 then ADC input max. value is also 3V3. So for the calculation it would be 3V3/1024 * analogRead / 10. For your example the two values in the I/O sample packet are 0x53 (MSB) and 0x00 (LSB) which is 83 in decimal. (3V3/1024) * 83 = 0,2674 V = 267,4 mV / 10 = 26,74°C. That value might be ok if your room temperature is that high ;)

According to the datasheet the LM35DZ operates from 4 to 30 volts. 3V3 is less than that - maybe that's the problem, if you get any wrong values.

How did you measure the 0.31V output? Was Vcc > 4 volts?

If you need a temperature sensor which works with 3V3, then try TMP36.

markbee

Ok ok ....My sensor is wired to a 4.5V battery with my board for the xbee module , which have a regulator to give 3V3 to the Xbee module , so it's not the problem .

I bought TMP36, but it's Farenheit sensor, and I'd like Celsius sensor, that's why I chose it.

I measure my 0.31V output with a voltmeter in the output sensor pin directly, and Vcc is 4.5V , so the sensor should work correctly.

I think your formula is good, I'll test it as soon as I m coming home .

Thank U very much for your help

Baklou

I bought TMP36, but it's Farenheit sensor, and I'd like Celsius sensor, that's why I chose it.

It's a temperature sensor. The output may documented in mV/*F or mV/*C, but either way, it will just output a voltage. That voltage can mapped to a *F value or to a *C value just as easily.

Yes you're right . the only thing which change is the wiring .... to 3V3 or 5V .

Thank you for your advices guys !