The mystery deepens. I loaded the simple test program onto the Weather Shield and got valid temperature and humidity readings. But my weather station code on the Weather Shield always returns valid temperature but zero for humidity. So the problem can’t be interference from the Shield’s onboard I2C sensors.
I ran the weather code on the stand-alone Photon. Again, I got valid temp. but zero humidity. So there must be something in the weather code it doesn’t like. But what? This program is 3000 lines long.
I tried adding the Sparkfun Weather library and the calls to the Weather Shield’s onboard I2C sensors to the simple code. I still got valid humidity. I tried placing the humidity read call at the very top of the weather code right after the am2315 object is defined before any other routines are run. I still get zero humidity from that program.
The am2315 library is looking for a device at 0x5C. But there is a Github post (http://github.com/kizniche/Mycodo/issues/315) claiming that newer AM2315’s use 0x57. So I tried setting #define AM2315_I2CADDR 0x57
in both programs, but that didn’t change anything. I still get no humidity when running the weather code.
Then I ran the I2C scanner again. Now it’s saying “no devices found” on the standalone Photon, and only the two onboard sensors on the Shield Photon. I’m like, how does that happen? How can it not find the am2315 but I can still get readings from it - unless I’m using it from my long program.
At this point I don’t even know how to troubleshoot this issue.
So I found a function in the library that supposedly reads both t and h in one call eliminating I2C timing issues. But when I put readTemperatureAndHumidity(t, h) ;
in my program, it won’t compile: am2315test.ino:72:36: 'readTemperatureAndHumidity' was not declared in this scope
That code is posted here: https://go.particle.io/shared_apps/5c043ec99264517dfa0001f3
// H sensor goes to sleep after 3 seconds so 1st call is to wake it up.
humidity = min (am2315.readHumidity(), 99) ;
byte n ;
for (n=0; n < 10; n++)
delay (100) ; // Very important to allow next I2C call to work.
humidity = min (am2315.readHumidity(), 99) ; // Read H twice according to spec sheet.
Serial.print ("am2315 H=") ;
Serial.println (humidity) ;
Could you comment out the for-loop? - I’m not sure if your sensor is really sleeping.
Eventually it will be swallowed when reading the values.
This sure looks like 0x5C (1011100b) to me. SDA (data) is on top, SCL (clock) is below. From the start point (where both signals go low) you can clearly make out the bits. So my device, even though it’s new as of late 2018, is not 0x57.
Notice also that there is very little lag in the rising edges, suggesting that pullup resistance is not the issue.
I’ve discovered something else interesting. In the AM2315 library, the functions readTemperature and readHumidity are essentially identical. They both send a query to the sensor for temperature and humidity. The only difference is that readTemperature only returns only the temperature value and readHumidity only returns the humidity value.
I’m having trouble reading my AM2315 temperature/humidity sensor. The temperature always works but the humidity always returns zero. Here is a sample of what the I2C bus is doing. SDA is on top, SCL is on the bottom. Notice how there are three spots near the left, center, and right where it looks like the clock stayed high for two cycles. I understand that the clock does not run when there is no data but that doesn’t look like the case here.
But I also see that it looks like this happens every nine cycles, corresponding perhaps to byte boundaries (plus an accept bit). Does anyone understand what this trace is showing? As an I2C noob, I’d appreciate any help.
Also, if you are using multiple I2C devices, it may be that the 3.3v w/ pullups should go into the breadboard’s side rails per the diagram rather than directly into the one device. I can’t remember if the BMP085 that I had was working per that diagram.
I was wondering. The datasheet says it works between 3.3 and 5.5 V, and they recommend 5.0.
In any case, the problem is solved, thanks to you. I added the 10K pullups and noticed that you were calling readTemperatureAndHumidity rather than readHumidity. Now that shouldn’t make any difference since readTemperature, readHumidity, and readTemperatureAndHumidity all simply call readData and then return just the piece(s) of info requested. But apparently it matters.
I changed my code from readTemperature followed by readHumidity to a single call to readTemperatureAndHumidity and it started working, with my simple program on the standalone Photon. I then put that readTemperatureAndHumidity call in my weather code and it still worked. I then ran my weather code on the WeatherShield and it still works (even though I didn’t add the pullups on that board).
So go figure. I still have no idea why this should work, nor why the I2C scanner doesn’t find this sensor but the pragmatist in me says it’s just time to let it go.
I think the morals here are:
To use this sensor, call readTemperatureAndHumidity, not readTemperature or readHumidity.
You may or may not need extra pullups on the I2C.
Be sure you know if you have a 0x5C or 0x57 sensor.
Anyway, mega thanks for replying. Now maybe I can get a good night’s sleep
I still don’t know why the SCL clock looks funny, but that’s probably because I2C hardware experts aren’t particularly going to be attracted to a thread called AM2315 Humidity.
Yeah I think I remember that calling the functions individually didn’t work but never investigated.
Pullups reduce the amperage through the sensor so it depends on how much it can tolerate. So it may or may not work or it may or may not affect the life of the sensor. I think it’s usually safer to have them.
The “stretched” SCL is created by an I2C STOP condition which brings the bus HIGH (pull-ups). In that period you will notice the SDA goes from HIGH to LOW while the SCL is HIGH. This is a START condition. The nine (9) LOW-to-HIGH SCL transitions are clocking data presented on SDA. The ninth transition is for the ACK bit. You will note that SDA is HIGH on that ninth clock indicating a NACK. So the device is NACKing the transaction.
I think I’m good. The Weather Shield has onboard pullups for I2C:
OK, thanks very much for the explanation. Do you know of any stand-alone I2C decoders? I know some scopes can do this but mine can’t. Sometimes it’s handy to be able to actually read the wire directly.
You are looking for a logic analyzer. You can get low cost ones which are clones of Saleae units. I have a DSLogic unit that works quite well. The Kingst logic analyzers seem to be good value as well though I have not tested either.