0

AM2315 Bad Data after 12 reads- some new info
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

AM2315 Bad Data after 12 reads- some new info

by easternstargeek on Wed Jun 26, 2013 11:33 am

Folks:
I have posted on this topic before, but further experimentation has provided some new information.

I have an AM2315 Temperature/Humidty sensor probe, and I am experiencing a vexing problem:

I hooked it up directly to a Teensy 2.0, and ran the example sketch that came with the library. (I added a 10 second delay in the setup procedure to give me time to start the serial monitor) . From a fresh power-up of the sensor, I get good reads for the first 10 cycles. On the 11th cycle and beyond, the data gets weird. Here is a snip from my Serial Monitor:

AM2315 Test!
Hum: 40.30
Temp: 23.60
Hum: 40.30
Temp: 23.60
Hum: 40.30
Temp: 23.60
Hum: 40.30
Temp: 23.60
Hum: 40.30
Temp: 23.60
Hum: 40.30
Temp: 23.60
Hum: 40.30
Temp: 23.60
Hum: 40.30
Temp: 23.60
Hum: 40.30
Temp: 23.60
Hum: 40.30
Temp: 23.60
Hum: 12.90
Temp: 3331.80
Hum: 13.00
Temp: 3331.80
Hum: 12.90
Temp: 3331.80
Hum: 13.00
Temp: 3331.80
Hum: 13.00
Temp: 3331.80
Hum: 13.00
Temp: 3331.80
Hum: 12.90
Temp: 3331.80
Hum: 13.00

If I reset the Teensy, I get nothing but bad data, similar to what you see above. The only way to clear it is to cycle power to the sensor, then the same pattern as above appears. (This is the new part- the sensor power-cycling thing)

By the way, when in the "bad data" phase, the Humidity value does change with the environment- I breathed on the sensor, probably enough to register a 99.9% RH level, and the "bad" value peaked at around 88%. I saw it go up and down rather normally. The curious thing is that the temperature value never deviates from 3331.80, even following some gentle heating with a lamp over several minutes. This is also new information.

This is frustrating. I really like the form factor of this sensor, and I need it badly for an important project. It's of no use to me if I can't make it work with my Teensy 2.0.

Do you think that a second look at your library is in order? I found the data sheet to be a difficult read. Maybe there is something else lurking in there.

Any help would be appreciated!
Last edited by easternstargeek on Mon Jul 08, 2013 8:10 pm, edited 3 times in total.

easternstargeek
 
Posts: 344
Joined: Mon Dec 13, 2010 1:39 pm
Location: Upper Eastern Tennessee

Re: AM2315 Bad Data after 12 reads- some new info

by anthropophage on Wed Jun 26, 2013 3:36 pm

Do your AM2315 is operated with 5V? I had similar problems with 3.3 Volts
anthropophage
 
Posts: 1
Joined: Wed Jun 26, 2013 3:34 pm

Re: AM2315 Bad Data after 12 reads- some new info

by easternstargeek on Wed Jun 26, 2013 3:43 pm

Yes, my Teensy 2.0 is configured for 5v operation.

By the way, I tried this out on a Teensey 3.0 and it worked just fine. Go figure...

easternstargeek
 
Posts: 344
Joined: Mon Dec 13, 2010 1:39 pm
Location: Upper Eastern Tennessee

Re: AM2315 Bad Data after 12 reads- some new info

by paulstoffregen on Thu Jun 27, 2013 6:26 am

You might try editing the library to uncomment this line:

Code: Select all | TOGGLE FULL SIZE
//Serial.println(reply[i], HEX);


Then the library will print the actual bytes it's receiving from the sensor. Maybe that will reveal something?

paulstoffregen
 
Posts: 434
Joined: Sun Oct 11, 2009 11:23 am
Location: Portland, Oregon, USA

Re: AM2315 Bad Data after 12 reads- some new info

by easternstargeek on Sat Jul 06, 2013 10:23 pm

Folks:
Looks like I probably found the problem-

Evidently, the AM2315 doesn't like being pestered too frequently.
As it is, the Library has to send Wire reads twice in succession to work around a bug that seems to have been encountered by the Adafruit team.

Adding a short delay between sensor reads seems to keep the data from getting scrambled.
(See notes in code, below)

The delay time was chosen empirically for the Teensy 2.0 platform. For some reason, the delay is not needed
for the Teensy 3.0 unit, or the Arduino UNO, which were also tested.

I will re-work the library so that it is only necessary to read the sensor once to get the Temperature and Humidity data at the same time,
and see if I can also find some additional information buried in the data sheet.

(h/t to Paul for his excellent suggestion, which helped crack the mystery!)

Code: Select all | TOGGLE FULL SIZE
#include <Wire.h>
#include <Adafruit_AM2315.h>

/***************************************************
  This is an example for the AM2315 Humidity + Temp sensor

  Designed specifically to work with the Adafruit BMP085 Breakout
  ----> https://www.adafruit.com/products/1293

  These displays use I2C to communicate, 2 pins are required to 
  interface
  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries. 
  BSD license, all text above must be included in any redistribution
 ****************************************************/

// Connect RED of the AM2315 sensor to 5.0V
// Connect BLACK to Ground
// Connect WHITE to i2c clock - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 5
// Connect YELLOW to i2c data - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 4

Adafruit_AM2315 am2315;

void setup() {
  Serial.begin(9600);
  Serial.println("AM2315 Test!");

  if (! am2315.begin()) {
     Serial.println("Sensor not found, check wiring & pullups!");
     while (1);
  }
}

void loop() {
  Serial.print("Hum: "); Serial.println(am2315.readHumidity());
  delay(2); //<-- ADDED BY ESG TO ELIMINATE BAD DATA PROBLEM, NOT PART OF ORIGINAL EXAMPLE
  Serial.print("Temp: "); Serial.println(am2315.readTemperature());

  delay(1000);
}

easternstargeek
 
Posts: 344
Joined: Mon Dec 13, 2010 1:39 pm
Location: Upper Eastern Tennessee

Re: AM2315 Bad Data after 12 reads- some new info

by paulstoffregen on Mon Jul 08, 2013 2:30 am

Glad you found the problem! :)

If anyone from Adafruit is still reading this, it might be good to think about updating this library? At first glance, this might seem like a Teensy-only problem. But Teensy 2.0 uses EXACTLY THE SAME 16 MHz AVR processor and Wire library as normal Arduino. The only difference is Teensy 2.0 has faster USB (about 15X faster than Uno, 3X faster than Leonardo) Serial.print(), digitalWrite() and other software-based optimizations.

This failure on Teensy 2.0 with the normal Arduino Wire library is a pretty strong sign the library and its example code probably just barely meets the timing requirements on normal Arduino boards.

paulstoffregen
 
Posts: 434
Joined: Sun Oct 11, 2009 11:23 am
Location: Portland, Oregon, USA

New AM2315 Library- Temp & Humidity in a single function call

by easternstargeek on Mon Jul 08, 2013 6:25 pm

I've already done it, and am testing now. So far, so good!:

The trick is to not read the sensor too frequently. (like <10mS interval).
Unlike the previous approach, my library modification gets the Temperature and Humidity data in a single read. It is returned via an array, using a pointer. This method can be a little difficult for inexperienced programmers to understand at first, but the example should make it clear. (There is an excellent explanation of this technique given in Oxer & Blemings, Practical Arduino, in Chapter 16, where the development of a touchscreen library is explained)

I have been running this on a Teensy 2.0 for several hours. Previously, problems would have showed up within seconds. Most applications would never need to read it more frequently than once per second, anyway.

Header file: ESG_AM2315.h

Code: Select all | TOGGLE FULL SIZE
/***************************************************
  This is a library for the AM2315 Humidity Pressure & Temp Sensor

  Designed specifically to work with the AM2315 sensor from Adafruit
  ----> https://www.adafruit.com/products/1293

  These displays use I2C to communicate, 2 pins are required to 
  interface
  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries. 

Additional improvements added by Daniel Sandoval/EasternStarGeek 
8 July, 2013.  (Parent Library: Adafruit_AM2315)

  BSD license, all text above must be included in any redistribution
 ****************************************************/

#if (ARDUINO >= 100)
 #include "Arduino.h"
#else
 #include "WProgram.h"
#endif
#include "Wire.h"

#define AM2315_I2CADDR       0x5C
#define AM2315_READREG       0x03

class ESG_AM2315 {
 public:
  ESG_AM2315();
  //boolean begin(void);
  boolean readData(float *dataArray); 
 
private:
  float humidity, temp;
};



Library File: ESG_AM2315.cpp file:

Code: Select all | TOGGLE FULL SIZE
/***************************************************
  This is a library for the AM2315 Humidity & Temp Sensor

  Designed specifically to work with the AM2315 sensor from Adafruit
  ----> https://www.adafruit.com/products/1293

  These displays use I2C to communicate, 2 pins are required to 
  interface
  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries. 

Additional improvements added by Daniel Sandoval/EasternStarGeek 
8 July, 2013.  (Parent Library: Adafruit_AM2315)

BSD license, all text above must be included in any redistribution
 ****************************************************/

#include "ESG_AM2315.h"
#include <util/delay.h>

ESG_AM2315::ESG_AM2315() {
}

boolean ESG_AM2315::readData(float *dataArray) {
  uint8_t reply[10];
 
  Wire.beginTransmission(AM2315_I2CADDR);
  Wire.write(AM2315_READREG);
  Wire.write(0x00);  // start at address 0x0
  Wire.write(4);  // request 4 bytes data
  Wire.endTransmission();


  // for reasons unknown we have to send the data twice :/
  // whats the bug here?
  Wire.beginTransmission(AM2315_I2CADDR);
  Wire.write(AM2315_READREG);
  Wire.write(0x00);  // start at address 0x0
  Wire.write(4);  // request 4 bytes data
  Wire.endTransmission();
 

  Wire.requestFrom(AM2315_I2CADDR, 8);
  for (uint8_t i=0; i<8; i++) {
    reply[i] = Wire.read();
    //Serial.println(reply[i], HEX);
  }
 
  if ((reply[0] == AM2315_READREG) &&
  (reply[1] == 4))  {
 
  humidity = reply[2];
  humidity *= 256;
  humidity += reply[3];
  humidity /= 10;
 
  dataArray[0] = humidity;

  temp = reply[4];
  temp *= 256;
  temp += reply[5];
  temp /= 10;
 
  dataArray[1] = (temp * 1.8)+32;

  return true;
}

else  {
dataArray[0] = NAN;
dataArray[1] = NAN;
return false;
}

}


/*********************************************************************/


Example Sketch:

Code: Select all | TOGGLE FULL SIZE
#include <Wire.h>
#include <ESG_AM2315.h>

/***************************************************
  This is an example for the AM2315 Humidity + Temp sensor

  Designed specifically to work with the Adafruit BMP085 Breakout
  ----> https://www.adafruit.com/products/1293

  These displays use I2C to communicate, 2 pins are required to 
  interface
  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries. 
 
  Additional improvements added by Daniel Sandoval/EasternStarGeek 
  8 July, 2013.  (Parent Library: Adafruit_AM2315)
 
  This version gets the Temperature and Humidity data with a single read, and is
  believed to solve some prior timing problems in the original.
 
  Be careful with return data array indexing!  Follow this example closely.

  BSD license, all text above must be included in any redistribution
 ****************************************************/

// Connect RED of the AM2315 sensor to 5.0V
// Connect BLACK to Ground
// Connect WHITE to i2c clock - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 5
// Connect YELLOW to i2c data - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 4

ESG_AM2315 am2315;

float dataAM2315[2];  //Array to hold data returned by sensor.  [0,1] => [Humidity, Temperature]
boolean OK;  // 1=successful read

void setup() {
  Serial.begin(9600);
  Serial.println("AM2315 Test!");
 }

void loop() {
  OK = am2315.readData(dataAM2315);
 
  if (OK) {
  Serial.print("Hum: "); Serial.println(dataAM2315[0]);
  Serial.print("TempF: "); Serial.println(dataAM2315[1]);
  }
else
Serial.println("Sensor not found, check wiring & pullups!");

  delay(1000);
}
Last edited by easternstargeek on Tue Jul 09, 2013 12:14 am, edited 1 time in total.

easternstargeek
 
Posts: 344
Joined: Mon Dec 13, 2010 1:39 pm
Location: Upper Eastern Tennessee

Re: AM2315 Bad Data after 12 reads- some new info

by adafruit_support_mike on Mon Jul 08, 2013 11:01 pm

AWESOME work, guys! That's a first class piece of troubleshooting and debugging.

@EasternStarGeek, I've just bought you a "Reverse Engineer" skill badge ( http://www.adafruit.com/products/489 ) which is waiting for you in all its lenticular goodness.

@Paul, since it takes some doing to measure up to a guy who has his own whole platform, I hereby declare you Babbage and Lovelace Awesome ( http://sydneypadua.com/2dgoggles/ ) and there's an Ada Lovelace skill badge waiting for you.

Send a note to support@adafruit.com with a link to this thread and they'll set you up.
When you void a product warranty, you give up your right to sue the manufacturer if something goes wrong and accept full responsibility for whatever happens next. And then you truly own the product.

adafruit_support_mike
 
Posts: 58843
Joined: Thu Feb 11, 2010 2:51 pm

Re: AM2315 Bad Data after 12 reads- some new info

by easternstargeek on Tue Jul 09, 2013 12:11 am

Thanks, Mike-

I'm still working on some improvements to the Library. Stay tuned!

easternstargeek
 
Posts: 344
Joined: Mon Dec 13, 2010 1:39 pm
Location: Upper Eastern Tennessee

Re: AM2315 Bad Data after 12 reads- some new info

by gewe on Tue Jul 09, 2013 3:50 am

hello,
It seems there is a timing problem. when I put a 'delay(10);' (I just tested some values) between reading out humidity and temperature everything works fine. before that I got only messy temperature readings.

//read AM2315
humidity = am2315.readHumidity();
delay(10);
temperature = am2315.readTemperature();

I hope it will help
gewe
 
Posts: 1
Joined: Tue Jul 09, 2013 3:32 am

Re: AM2315 Bad Data after 12 reads- some new info

by adafruit_support_rick on Tue Jul 09, 2013 7:26 am

@gewe - thanks for the tip. As easternstargeek points out:
EasternStarGeek wrote:The trick is to not read the sensor too frequently. (like <10mS interval).

adafruit_support_rick
 
Posts: 35095
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: AM2315 Bad Data after 12 reads- some new info

by easternstargeek on Tue Jul 09, 2013 2:30 pm

As far as I can tell from the data sheet, you shouldn't read the sensor more frequently than every 2 seconds, although I think that has more to do with the way the readings are actually taken.

The errors I got when querying the sensor quickly were pretty repeatable.

Before going further, a brief Earth Science review is in order: Relative Humidity is the percentage of the maximum moisture that air can hold at a given temperature. Cool air holds less moisture than warm air. Eventually, the air becomes saturated and can hold no more moisture. The temperature at which that happens is called the Dew Point temperature. Relative Humidity is a much more useful predictor of human comfort than absolute moisture, because it is inversely related to the rate of perspiration evaporation.
All simple measurement instruments that respond to moisture are responding to Absolute Moisture. In the old days, meterologists used a Sling Psychrometer to indirectly measure Relative Humidity. http://en.wikipedia.org/wiki/Hygrometer

For those who have examined the library and data sheet:

The sensor consumes a fair bit of power, and like all things electronic, will self-heat as a result. All humidity sensor elements respond to absolute moisture, therefore calculating meaningful Relative Humidity readings requires accurate temperature readings.

To avoid self-heating, the sensor goes to sleep in between readings, consuming just enough power to see if a query comes in on the I2C bus. The data sheet outlines a specific procedure for doing that, and following the wake-up call, it will then be able to respond to requests for data. It's pretty tricky from a timing point of view, and I'm still trying to figure out some of the quirks. I have one on the bench right now that I've been testing for a few days.

According to the data sheet, the wake-up procedure requires the following Wire transaction:

Code: Select all | TOGGLE FULL SIZE
#define AM2315_I2CADDR  0x5C
Wire.beginTransmission(AM2315_I2CADDR);
delay(3);
Wire.endTransmission();


The original Adafruit library did it differently, by sending two complete data read requests in succession. and although it sort of works, it might introduce problems up the road on certain platforms. I'm currently testing the above wake-up procedure, and so far, it's working well.

Finally, the sensor calculates a checksum on the temperature/humidity data and makes it available for checking data integrity, so it would be a shame not to include it. That will take me a little time to implement, as it is the dreaded "CRC-16 Polynomial" type, which is tricky to code.

It's coming, however, so stay tuned!
Last edited by easternstargeek on Tue Jul 09, 2013 2:55 pm, edited 3 times in total.

easternstargeek
 
Posts: 344
Joined: Mon Dec 13, 2010 1:39 pm
Location: Upper Eastern Tennessee

Re: AM2315 Bad Data after 12 reads- some new info

by paulstoffregen on Tue Jul 09, 2013 2:45 pm

Perhaps a better design for a "user friendly" library would include buffered copy of the last actual measurement and a millis() timestamp of when that measurement was read from the sensor.

Then the read function could check the elapsed time on each request. If it's less than 2 seconds, the previous data could be returned from the buffer. If more than 2 seconds, wake the sensor to take a new measurement, update the buffer and return the new data.

Novice users could read the data at any rate, but the library would automatically manage how quickly the sensor is really read. There should probably be strongly worded comments inside the library about why this throttling is needed to avoid self heating.

paulstoffregen
 
Posts: 434
Joined: Sun Oct 11, 2009 11:23 am
Location: Portland, Oregon, USA

Re: AM2315 Bad Data after 12 reads- some new info

by easternstargeek on Tue Jul 09, 2013 2:50 pm

Thanks, Paul- it's a good idea, and I may incorporate it.

I am always ambivalent about "goof-proofing" libraries, because most users don't take the time to "look under the hood" of the function, and so the more complicated they are, the more likely a user will have difficulty troubleshooting the projects on which they depend. It's a delicate balancing act. I personally like it when my project code is as transparent as possible, but there are pitfalls to that, too.

It's all about style!

(and good documentation!)

easternstargeek
 
Posts: 344
Joined: Mon Dec 13, 2010 1:39 pm
Location: Upper Eastern Tennessee

Please be positive and constructive with your questions and comments.