-
Notifications
You must be signed in to change notification settings - Fork 137
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
I2C read fails on "readByte" from AM2315 #103
Comments
I haven't checked what that requestFrom actually does but I suspect it's doing an actual i2c request for those 8 bytes, those 8 read() could just be reading from an internal buffer or anyway, not actually sending a read request like you are doing in Swift. |
Thanks @uraimo I tried both of the options you suggested, but no luck. With the This is how the manufacturer's python library for the AM2315 reads the data. def _read_data(self):
count = 0
tmp = None
powercyclecount = 0
while count <= MAXREADATTEMPT:
try:
try:
self._device.write_byte_data(AM2315_I2CADDR, AM2315_READREG, 0x00)
time.sleep(0.050)
except:
if (AM2315DEBUG == True):
print "Wake Byte Fail"
time.sleep(2.000)
self._device.write_byte_data(AM2315_I2CADDR, AM2315_READREG, 0x00)
time.sleep(0.001)
#self._device.write_byte_data(AM2315_I2CADDR, AM2315_READREG, 0x00)
#time.sleep(0.001)
#self._device.write_byte_data(AM2315_I2CADDR, AM2315_READREG, 0x00)
time.sleep(0.050)
# 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)
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
if (self.AM2315PreviousTemp != -1000): # ignore first time
if (self.humidity <0.01 or self.humidity > 100.0):
# OK, humidity is bad. Ignore
if (AM2315DEBUG == True):
print ">>>>>>>>>>>>>"
print "Bad AM2315 Humidity = ", self.temperature
print ">>>>>>>>>>>>>"
self.badreadings = self.badreadings+1
tmp = None
else:
if (abs(self.temperature - self.AM2315PreviousTemp) > 10.0):
# OK, temp is bad. Ignore
if (AM2315DEBUG == True):
print ">>>>>>>>>>>>>"
print "Bad AM2315 Temperature = ", self.temperature
print ">>>>>>>>>>>>>"
self.badreadings = self.badreadings+1
tmp = None
else:
# Good Temperature
self.AM2315PreviousTemp = self.temperature
else:
# assume first is good temperature
self.AM2315PreviousTemp = self.temperature
# IF WE HAVE DATA, LETS EXIT THIS LOOP
if tmp != None:
break
except Exception as ex:
if (AM2315DEBUG == True):
template = "An exception of type {0} occurred. Arguments:\n{1!r}"
message = template.format(type(ex).__name__, ex.args)
print message
#print traceback.format_exc()
print "AM2315readCount = ", count
count += 1
self.retrys += 1
time.sleep(0.10)
# only do three power cycle attempts
if (self.powerpin <> 0):
if (count > MAXREADATTEMPT):
self.powerCycleAM2315()
if (powercyclecount <=2):
powercyclecount +1
count = 0
if (AM2315DEBUG == True):
print "--->looking at good data"
# GET THE DATA OUT OF THE LIST WE READ
self.humidity = ((tmp[2] << 8) | tmp[3]) / 10.0
self.temperature = (((tmp[4] & 0x7F) << 8) | tmp[5]) / 10.0
if (tmp[4] & 0x80):
self.temperature = -self.temperature
self.crc = ((tmp[7] << 8) | tmp[6])
# Verify CRC here
# force CRC error with the next line
#tmp[0] = tmp[0]+1
t = bytearray([tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5]])
c = self.verify_crc(t)
if (AM2315DEBUG == True):
print "AM2315temperature=",self.temperature
print "AM2315humdity=",self.humidity
print "AM2315crc=",self.crc
print "AM2315c=",c
if (self.crc != c) or (c == 0):
#if self.crc != c:
if (AM2315DEBUG == True):
print "AM2314 BAD CRC"
self.badcrcs = self.badcrcs + 1
self.crc = -1
else:
self.goodreads = self.goodreads+1 I tried to follow how they did it, but checking how they use |
Ciao, sorry for the delay, it looks like they implemented most of the layer above the ioctl instead of using a python smbus library. The problem is here:
That's not actually a block_data_read... but an I2C_RDWR(0x707) that reads and writes at the same time... and that is not implemented in SwiftyGPIO (that implements only smbus ioctl calls) because I never found a device that supported it. Our I2C_RDWR should look like this, starting from their implementation:
|
Board Type
Raspberry Pi 3B+
Operating System
Raspbian Buster 10
Swift Version
Swift pre-built version 5.1.3 from https://github.com/uraimo/buildSwiftOnARM/releases/tag/5.1.3
Description
I am trying to create a library to control the AM2315 temperature and humidity sensor using SwiftyGPIO.
I am using Arduino_AM2315 library as basis to understand how to obtain the sensor's readings. Here is the code snippet from the previously mentioned library:
And here is the Swift version of the code above:
According to the documentation, I am expecting to receive a response in the format of:
But whenever I run my Swift code, it only successfully retrieves the first byte of the expected sequence: 0x03. When it tries to read the second one onwards, it always crashes, and the error it outputs is:
It is worth to mention that I have also tried using the
readByte(_ address: Int, command: UInt8)
andreadData(_ address: Int, command: UInt8)
with no success. The former fails in the exact same manner as mentioned before, and the later just return a array full of zeroes.The text was updated successfully, but these errors were encountered: