am2315 for raspberry pi in python

Our weekly LIVE video chat. Every Wednesday at 8pm ET!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: am2315 for raspberry pi in python

Post by adafruit_support_rick »

If you read from register 3 instead of register 0, you'll at least get 3 back in the first byte. But the rest of it will be nonsense.
I'm starting to think that this can't be done with the R Pi's I2C driver.

NerdWorld
 
Posts: 14
Joined: Sat Jan 18, 2014 5:58 pm

Re: am2315 for raspberry pi in python

Post by NerdWorld »

At least if it can be done, it will take somebody cleverer than me <sigh>

I was able to find this code on line that is supposed to work. It uses a more obscure basic python library. The code seems pretty straightforward, although I don't know how to make it work. It might give you (or someone on this forum) some ideas.

https://code.google.com/p/am2315-python-api/

Here is the relevant code from the git repository:

Code: Select all

!/usr/bin/env python3
import quick2wire.i2c as i2c
import array 
import sys
import time
import math 

R_CONST=8314.3
MW_CONST=18.016
AM2315_I2CADDR = 0x5c
AM2315_WAITTIME = 0.150
MAXTRYS=3
FUNCTION_CODE_READ = 0x03
readBytes = array.array ("B",[0x00,0x04])
class AM2315(object): 
    def __init__(self): 
        pass
    def __del__(self): 
        pass
    def values(self): 
        i=0
        errcode=0 
        hum = 999
        temp = 999
        while i <= MAXTRYS:
          with i2c.I2CMaster() as bus: 
            try:
               bus.transaction(i2c.writing_bytes(AM2315_I2CADDR, 
                   FUNCTION_CODE_READ,*readBytes )) 
               time.sleep(AM2315_WAITTIME)
               read_results = bus.transaction(i2c.reading(AM2315_I2CADDR, 8))
#               print(read_results)
               break
            except: 
               i = i+1 
        if i > MAXTRYS:
           errcode=1
        else:
           s=bytearray(read_results[0])
           crc = 256*s[7]+s[6]
           t = bytearray([s[0],s[1],s[2],s[3],s[4],s[5]])
           c = self.crc16(t) 
           if crc != c:
             errcode=2
           else:
             hum = (256*s[2]+s[3])/10
             temp = (256*s[4]+s[5])/10
        return hum,temp,errcode   

Vince8134
 
Posts: 13
Joined: Wed Dec 25, 2013 4:38 pm

Re: am2315 for raspberry pi in python

Post by Vince8134 »

It has worked for me. I can read both temperature and humidity, although some records dont work : when i try to get two records of the data too closely. And it seems there is a bit of delay before updating the data.

User avatar
adafruit_support_rick
 
Posts: 35092
Joined: Tue Mar 15, 2011 11:42 am

Re: am2315 for raspberry pi in python

Post by adafruit_support_rick »

Can you share your code, please?

User avatar
ydna
 
Posts: 15
Joined: Sun Jul 21, 2013 7:47 pm

Re: am2315 for raspberry pi in python

Post by ydna »

I tried the code above I get a syntax error in the line that has BusNumber.write...

NerdWorld
 
Posts: 14
Joined: Sat Jan 18, 2014 5:58 pm

Re: am2315 for raspberry pi in python

Post by NerdWorld »

ydna, you shouldn't get a syntax error there, since the "try" command would allow the error to be ignored. You probably have some type of typo. I was able to get the code to execute. Are you using Python 2.x or python 3? (This was written for python 2)

On the other hand, the code itself won't give you the sensor readings. I still haven't figured it out.

I was hoping that Vince8134 would post his code that worked.

Vince8134
 
Posts: 13
Joined: Wed Dec 25, 2013 4:38 pm

Re: am2315 for raspberry pi in python

Post by Vince8134 »

I'm back to my Raspberry tonight, sorry for the delay, I was away this WE.
I will be able to post it, but basically, I just followed what I got from the link previously posted on google. So, not sure it will be very helpful.
Anyway, see you tonight (in France, so, in several hours).

Vince8134
 
Posts: 13
Joined: Wed Dec 25, 2013 4:38 pm

Re: am2315 for raspberry pi in python

Post by Vince8134 »

I have this :

Code: Select all

[#!/usr/bin/env python3
#
import quick2wire.i2c as i2c
import array
import sys
import time
import math
#
R_CONST=8314.3
MW_CONST=18.016
AM2315_I2CADDR = 0x5c
AM2315_WAITTIME = 0.150
MAXTRYS=3
FUNCTION_CODE_READ = 0x03
readBytes = array.array ("B",[0x00,0x04])
class AM2315(object):
    def __init__(self):
        pass
    def __del__(self):
        pass
    def values(self):
        i=0
        errcode=0
        hum = 999
        temp = 999
        while i <= MAXTRYS:
          with i2c.I2CMaster() as bus:
            try:
               bus.transaction(i2c.writing_bytes(AM2315_I2CADDR,
                   FUNCTION_CODE_READ,*readBytes ))
               time.sleep(AM2315_WAITTIME)
               read_results = bus.transaction(i2c.reading(AM2315_I2CADDR, 8))
#               print(read_results)
               break
            except:
               i = i+1
        if i > MAXTRYS:
           errcode=1
        else:
           s=bytearray(read_results[0])
           crc = 256*s[7]+s[6]
           t = bytearray([s[0],s[1],s[2],s[3],s[4],s[5]])
           c = self.crc16(t)
           if crc != c:
             errcode=2
           else:
             hum = (256*s[2]+s[3])/10
             temp = (256*s[4]+s[5])/10
        return hum,temp,errcode   
    def humidity(self):
        x=self.values()
        return self.values()[0]

    def temperature(self):
        return self.values()[1]

    def SDD(self,T,mode):
        return 6.1078 * math.pow(10,((self.a(mode)*T)/(self.b(mode)+T)))
    def DD(self,mode):
        r = self.humidity()
        T = self.temperature()
        return r/100 * self.SDD(T,mode)
    def a(self,mode):
        T = self.temperature()
        if T >= 0:
           return 7.5
        if T < 0 and mode == 0 :
           return 7.6
        if T < 0 and mode == 1 :
           return 9.5
    def b(self,mode):
        T = self.temperature()
        if T >= 0:
           return 237
        if T < 0 and mode == 0 :
           return 240.7
        if T < 0 and mode == 1 :
           return 265.5
    def TD(self,mode):
        v=math.log10(self.DD(mode)/6.1078)
        return (self.b(mode)*v)/(self.a(mode)-v)
    def RR(self,mode):
        T = self.temperature()
        return 100*self.SDD(self.TD(T),mode) / self.SDD(T,mode)
    def AFr(self,mode):
        T = self.temperature()
        return math.pow(10,5)*MW_CONST/R_CONST*self.DD(mode)/self.TK(T)
    def TK(self,T):
        return T+273.15
    def crc16(self, char):
         crc = 0xFFFF
         for l in char:
               crc = crc ^ l
               for i in range(1,9):
                   if (crc & 0x01):
                      crc = crc >> 1
                      crc = crc ^ 0xA001
                   else:
                      crc = crc >> 1
         return crc
/code]

And this :
[code]from AM2315 import AM2315
MAXTRIES = 5
sensor=AM2315()
for i in range (0,MAXTRIES):
  x = sensor.values()
  if x[2] != 0:
     next
#<<<<<<< HEAD
#  if (x[0] > 0 and x[1] != 0) or (x[0]>0 and i>MAXTRIES-1) :
  print(x[0],x[1],x[2])
  break
#if i > 0 :
#  print(i ,"retries needed")
#=======
  print(x[0],x[1],x[2])
  break
#>>>>>>> 3230c415d422a5ac45564e6e2a7fc8194b5c3b45

User avatar
mglenn12
 
Posts: 39
Joined: Thu Dec 12, 2013 11:56 am

Re: am2315 for raspberry pi in python

Post by mglenn12 »

there are 2 of us trying to find a way to read the AM2315. I cannot even get the i2c to indicate its presence with repeated "i2cdetect -y 1". What was your 'trick'?

thanks, Mike

Vince8134
 
Posts: 13
Joined: Wed Dec 25, 2013 4:38 pm

Re: am2315 for raspberry pi in python

Post by Vince8134 »

Sorry, I can't edit my previous post, but there are 2 pieces of code.

I followed this schema based on Arduino :
https://dlnmh9ip6v2uc.cloudfront.net/as ... 8b4568.png

NerdWorld
 
Posts: 14
Joined: Sat Jan 18, 2014 5:58 pm

Re: am2315 for raspberry pi in python

Post by NerdWorld »

Mike, if the repeated i2cdetect doesn't work, you've probably made a wiring error of some type.

Here is a diagram of how I wired the Pi to the AM2315.
Wiring Diagram
Wiring Diagram
Temperature Sensor - Raspberry Pi Wiring Diagram.png (62.75 KiB) Viewed 2285 times

NerdWorld
 
Posts: 14
Joined: Sat Jan 18, 2014 5:58 pm

Re: am2315 for raspberry pi in python

Post by NerdWorld »

Got it!

I've simplified the code found on the google site, and now have the sensor working.

Couple of caveats:

1. The new code requires Python 3, but the more traditional smbus library only works in python 2. If you want to use this sensor, you've got to move on to python 3 (well, I needed the push anyway <grin>)
2. The required i2c library is not part of normal Raspian and has to be downloaded from a 3rd-party library. I've added comments in the code to show how to do this.
3. I still haven't figured out why my original code didn't work. Maybe it was a bug in the library. <sigh>


Comments and suggestions are welcome!

Code: Select all

#!/usr/bin/env python3
#
# AM2315.py
#
#
# A program to read the AM2315 Temperature and Humidity sensor
#
#
# Original code by Jorg Ehrsam found at https://code.google.com/p/am2315-python-api/ 
#  Simplified and commented by Casey Bralla ([email protected]) 2014-02-19
#
#
#  This program requires the quick2wire i2c library, which is not part of standard Raspian
#
#  To load it into Raspian, use these commands:
#
#   1. Add this line to /etc/apt/sources		deb http://dist.quick2wire.com/raspbian wheezy main
#   2. Add this line also						deb-src http://dist.quick2wire.com/raspbian wheezy main
#   3. Add the security key by typing (as root)	curl -L https://github.com/quick2wire/quick2wire-software-users/raw/master/software%40quick2wire.com.gpg.key | apt-key add -
#	4. Update the repositories					apt-get update
#	5. Load the libraries						apt-get install quick2wire-python3-api
#
#
#
import quick2wire.i2c as i2c
import array
import time
#
#
#
AM2315_I2cAddress 	= 0x5c
AM2315ReadCommand 	= 0x03
ReadBytesData 		= array.array ("B",[0x00,0x04])
#
AM2315_WaitTime 	= 0.150
#
MaxReadAttempts		= 3
ReadAttemptCounter	= 0
#
#
#
while ReadAttemptCounter <= MaxReadAttempts:
	#
	with i2c.I2CMaster() as bus:
		#
		try:
			#
			# Send the read sequence to the AM2315
			bus.transaction(i2c.writing_bytes(AM2315_I2cAddress,AM2315ReadCommand,*ReadBytesData ))
			#
			# Sleep a while to let it measure and calculate the values
			time.sleep(AM2315_WaitTime)
			#
			# Read back the measured values
			Read_Results = bus.transaction(i2c.reading(AM2315_I2cAddress, 8))
			#
			# print(Read_Results)
			#
			# Reset the Error Code
			errcode=0
			#
			# Break out of the loop since we have the data we need
			break
			#
			#
		except:
			#
			# The initial command sequence failed, which will wake up the sensor, so we tally the miss and try again
			ReadAttemptCounter = ReadAttemptCounter + 1
			#
			#
	#
	#
#
#
#
# Do we need to set an error code?
if ReadAttemptCounter > MaxReadAttempts:
	errcode=1
else:
	# If good data, then get the results in a good format
	AM2315Results	= bytearray(Read_Results[0])
	Humidity 		= ( (256 * AM2315Results[2]) + AM2315Results[3] )/10
	TemperatureC 	= ( (256 * AM2315Results[4]) + AM2315Results[5] )/10
	TemperatureF	= ( 9 * TemperatureC / 5 ) + 32
#
#
# print(errcode)
print(TemperatureF)
print(Humidity)

User avatar
ydna
 
Posts: 15
Joined: Sun Jul 21, 2013 7:47 pm

Re: am2315 for raspberry pi in python

Post by ydna »

nerdworld, i'm using python 2. I cant get that python 3 depandant code working.

User avatar
ydna
 
Posts: 15
Joined: Sun Jul 21, 2013 7:47 pm

Re: am2315 for raspberry pi in python

Post by ydna »

How do you install quick2wire on the pi. I cant install it in python3 because I dont have setup tools. But when I type 'sudo pip install setuptools' it says that it is already satisfied for python 2.7...How can you get setuptools for python3?

NerdWorld
 
Posts: 14
Joined: Sat Jan 18, 2014 5:58 pm

Re: am2315 for raspberry pi in python

Post by NerdWorld »

I'm still struggling with moving to Python 3 also, but I didnt' have much trouble loading the quickwire libraries. Here's what I did:

1. Add 2 lines to /etc/apt/sources
deb http://dist.quick2wire.com/raspbian wheezy main
deb-src http://dist.quick2wire.com/raspbian wheezy main

2. Add quickwire's security key, so apt will accept the foreign sources as valid
curl -L https://github.com/quick2wire/quick2wir ... om.gpg.key | sudo apt-key add -

(Note, copy this line directly, since it's easy to screw up the syntax.)

3. Update the resposity
apt-get update

(Note: You should see the quickwire repository loading.)

4. Install the libraries:
apt-get install quick2wire-api



If you get a message about "untrusted" something-or-other, then you probably didn't load the key properly.


That should do it. If it doesn't, then let me know what yoru errors were.

Locked
Please be positive and constructive with your questions and comments.

Return to “Ask an Engineer! VIDEO CHAT (closed)”