wbp
New Member
Posts: 26
|
Post by wbp on Oct 9, 2019 15:42:01 GMT -8
I finally got my SkyWeather built, and I was having problems with the AM2315 temperature/humidity sensor. The "testAM2315.py" program would sometimes return data, but most often it just froze. I decided to do some digging to see if I could figure out why.
I found some information from other people using this sensor that indicated that it needed at least 2 "wakeups", and it appeared that only one was being done in the SDL_Pi_AM2315/AM2315test.py function. I changed the code to loop on the wakeup until it worked, up to a preset number of times, then attempt to request the data it wants. that really seems to have helped.
I am a bit curious about the need to connect the AM2315 via one of the Grove PowerSave boards. From what I read on the net, this sensor powers itself down to avoid false readings from heating, which is why it needs to be woken up. If that's the case, why turn off the power?
I had a lot of trouble talking to the AM2315 while it was connected to the Grove PowerSave board, If I connect it directly to either the 6 Port I2C board or one of the I2C connectors on the Pi2Grover it works very reliably.
I will post a copy of my code changes so others can see if this helps them.
Will
|
|
|
Post by SDL on Oct 9, 2019 16:22:04 GMT -8
Will,
Indeed. Welcome to AM2315 land. The AM2315 will hang sometimes and hang the i2c bus. Hence the Grove Power Save. It requires a power down of the AM2315 (not just going to sleep).
The double tap to wake up the AM2315 is buried in the driver. What you are doing is OK, but it kind of duplicates what the driver is doing. Again, more AM2315 flakeyness.
And really, just a few in the last batch.
BP
|
|
wbp
New Member
Posts: 26
|
Post by wbp on Oct 9, 2019 17:15:37 GMT -8
I did not see anything in the driver that did a double wakeup. Are you talking about SDL_Pi_AM2315/AM2315.py? There is some code that could do a second wakeup, but with the try/except setup it never actually does that. If any one of the writes fail it bails and starts over. To do a wakeup you just have to keep sending them and ignore the errors. That's what I re-wrote. Before I changed the code it was failing 90% of the time. Now it works every time.
What started me on this was the AM2315 hanging and killing the entire program. Now it runs reliably.
Will
|
|
|
Post by SDL on Oct 10, 2019 8:31:42 GMT -8
Will,
I'm looking at that. I am not sure what I did and why I commented out the first one and didn't replace it. I'm going to check this out this afternoon. The last big change was to adjust the i2c bus to better match the AM2315 I2C specification, which I did. I may have hosed this up!
BP
|
|
wbp
New Member
Posts: 26
|
Post by wbp on Oct 10, 2019 13:53:25 GMT -8
Here are my mods to SDL_Pi_AM2315/AM2315.py
I added a new variable MAXWAKEUPS and changed MAXREADATTEMPT to 5:
# GLOBAL VARIABLES AM2315_I2CADDR = 0x5C AM2315_READREG = 0x03 MAXWAKEUPS = 5 # wbp MAXREADATTEMPT = 5 # wbp
I added this function:
def _wakeup(self): count = 0 while count < MAXWAKEUPS: count += 1 self.wakeups = count try: if (AM2315DEBUG == True): print ("AM2315 wakeup",count) self._device.write_byte_data(AM2315_I2CADDR, AM2315_READREG, 0x00) if (AM2315DEBUG == True): print ("AM2315 wokeup",count) time.sleep(0.10) # break except: if (AM2315DEBUG == True): print ("AM2315 wakeup failed",count) time.sleep(0.10)
This is the first section of _read_data() :
def _read_data(self): count = 0 tmp = None powercyclecount = 0
while count <= MAXREADATTEMPT:
try: if (AM2315DEBUG == True): print ("Attempting to wake up AM2315") # ??? wbp self._wakeup()
if (AM2315DEBUG == True): print ("req 4 bytes AM2315") # ??? wbp # TELL THE DEVICE WE WANT 4 BYTES OF DATA self._device.write_i2c_block_data(AM2315_I2CADDR, AM2315_READREG,[0x00, 0x04]) #self._device.writeList(AM2315_READREG,[0x00, 0x04]) # time.sleep(0.09) time.sleep(1.0) # ??? wbp if (AM2315DEBUG == True): print ("AM2315 read data") # ??? wbp tmp = self._device.am2315_read_i2c_block_data(AM2315_I2CADDR, AM2315_READREG,8) #tmp = self._device.readList(AM2315_READREG,8) self.temperature = (((tmp[4] & 0x7F) << 8) | tmp[5]) / 10.0 self.humidity = ((tmp[2] << 8) | tmp[3]) / 10.0 # check for > 10.0 degrees higher [... etc ...}
I also modified read_status_info() to return self.wakeups
Hope this helps. If I could remember how to do Git I'd clone it and make the mods so you could pull them but it's been too long since I've done that, sorry...
|
|
|
Post by SDL on Oct 12, 2019 9:14:14 GMT -8
Thank you Will. I've got my test unit sitting on the bench ready to go for my tests.
BP
|
|