AM2320 - temp / humidty

bobladell

New Member
Hi All - done a forum search and seems no one has done anything with the AOSONG AM2320 I2C based temp and humidity sensor.
That right - or have I missed something ?
Thanks
Bob
 

hippy

Technical Support
Staff member
I couldn't find anyone having used an AM2320 but it looks like it could be possible to use it with a PICAXE. There are some mentions in the datasheet about using a custom I2C mode and specific timing requirements but it should be possible to make it work, even if bit-banged I2C is required. The proof of that would however be in the doing of it.

If you have the device, or have experience of using it with something other than a PICAXE, have some understanding of I2C, it's probably worth trying, but also worth considering what else may be available which may be easier to use.

This is a good reference for comparing various humidity sensors -

http://www.kandrsmith.org/RJS/Misc/Hygrometers/calib_many.html

Note the comments about the AM3230 being intermittently unreliable above 50%RH. That may not be a problem if one can re-read the data when it's so obviously wrong ($00/$FF). It may also be an issue related to the timing and needing to wake it from sleep which the datasheet mentions, so may not be faulty operation.
 

bobladell

New Member
Hi Hippy - many thanks for confirming. I have a couple of AM2320 and am trying to get them working on an 18M2+ sitting on an AXE110. They looked dead easy to get running under PICAXE but proving hard work.

I also have an Arduino UNO and have the AM2320 working on that, so the sensors themselves are good, and provide nice stable T and RH figures so would be nice to use on my PICAXE based environmental monitor project.

I've also tried the PICAXE i2c Tutorial and the stuck i2c bus routine from one of the i2c PICAXE references - doesn't seem to be that.

i2c - should be easy..............

Code - AXE110 standard Wizard generated modded just to use a) the DS18B20 to show it's running (it was screwed into the board so why not), and b) the on board RTC, also why not for test, and to show me that the I2C bus is working and that I'm using the hi2c instructions correctly. I'm not working out the time - just getting some numbers back for debug.

main:
gosub read_sensors ; read the sensors
pause 1000
; gosub save_data ; save sensor readings in eeprom
; gosub inc_address ; update address to save to
; gosub wait_time ; wait until ready for next reading
goto main ; take next reading

; ****************************
; ***** Read sensor data *****
; ****************************

read_sensors:
high B.3 ; flash green LED
readtemp C.7, data7 ; read Temperature - DS18B20 - one wire
low B.3 ; end of green LED flash
;debug data7
sertxd ("DS Temp = ",#data7,CR,LF)

read_time:
hi2csetup i2cmaster, %11010000, i2cslow, i2cbyte ;Addr $D0
hi2cin 0,(secs,mins,hours,temp_byte,day,month)
pause 100
sertxd ("H = ",#hours," Min = ", #mins,CR,LF)

;AM2320 - temp and humidity I2C
hi2csetup i2cmaster, %10111000, i2cslow, i2cbyte ;Addr $B8
pause 1
hi2cout ($03,$00,$04) ;Addr+W (=$10), FnCode, StartAddr, No of Reg
pause 10
hi2cin (b20,b21,b22,b23,b24,b25,b27,b26) ;Am2320 response Address+R - $03,$04,RHHi,RHLo,THi,TLo,CRCLo,CRCHi
;AM reply
sertxd ("AM reply = ",#b20," FCode = ",#b21,CR,LF)

;RH Calc
;debug w11 ;b22, b23 = RH
sertxd ("RH = ",w11,CR,LF) ;RH to PC screen

;T Calc
;debug w12 ;b24, b25 = Temp
sertxd ("Temp = ",w12,CR,LF) ;Temp to PC screen

return

Tried changing the pauses from zero to about 2S, no difference. Also re-including the AM i2c address on the hi2cout and hi2cin lines......

I'm only getting zero's back from the Am2320 in the b2x registers - so indications are that I'm talking i2c OK - but not speaking the AM2320 language...........



Any ideas gratefully received

Bob
 

bobladell

New Member
.....and - the Arduino library contains the line #define AM2320_address (0xB8 >> 1) - so it seems to be using 7 bit addressing instead of PICAXE 8 bit. I've tried shifting right and using address $5C as well, also no luck.

Don't know what the PICAXE (or Arduino) do for the wake up mentioned in the AM2320 spec but would have thought that reading it as often as I am would be enough to wake it up ??

Bob
 

Aries

New Member
The Arduino code seems to be something like this ...
Code:
     Wire.beginTransmission(AM2320_address);      
     Wire.endTransmission();      
     // запрос 4 байт (температуры и влажности)      
     Wire.beginTransmission(AM2320_address);      
     Wire.write(0x03);// запрос      
     Wire.write(0x00); // с 0-го адреса      
     Wire.write(0x04); // 4 байта      
     if (Wire.endTransmission(1) != 0) return 1;      
     delayMicroseconds(1600); //>1.5ms      
     // считываем результаты запроса      
     Wire.requestFrom(AM2320_address, 0x08);       
     for (int i = 0; i < 0x08; i++) buf[i] = Wire.read();
This suggests you need to send a "wake-up" first which seems to be an empty message. The datasheet implies that the AM2320 shuts down after a temperature and humidity reading, so you will always need to wake it up, even if you are continuously communicating with it. I'm not sure how you send an empty message with hi2cout - I'm sure someone with more experience than I have can help you out.
 

hippy

Technical Support
Staff member
It does all look a little complicated reading the datasheet but the code in Post #3 looks reasonable enough and pretty close to what I would have tried as a first effort -
Code:
#Picaxe 18M2
#Terminal 4800
#No_Data

TestProgram:
  Do
    Pause 2000
    For b13 = 1 To 5
      Gosub ReadData
      If w0 = $0304 Then
        SerTxd( "Okay " )
      Else
        SerTxd( "FAIL " )
      End If
    Next
    SerTxd( CR, LF )
  Loop

ReadData:

  ; .-----.-----.-----.
  ; | $03 | $00 | $04 |
  ; `-----^-----^-----'
  ;  Read   Reg   Len
  ;
  ;       w0          w1          w2          w3
  ; .-----------.-----------.-----------.-----------.
  ; | $03 | $04 | $hh | $hh | $tt | $tt | crc | crc |
  ; `-----------^-----------^-----------^-----------'
  ;    b1    b0    b3    b2    b5    b4    b7    b6

  HI2cSetup I2CMASTER, $B8, I2CSLOW, I2CBYTE
  HI2cOut ( $03, $00, $04 )
  HI2cIn  ( b1,b0, b3,b2, b5,b4, b7,b6 )
  Return
I would expect that to hopefully show "FAIL Okay Okay Okay Okay" on each line. If so it means we are managing to wake the device up and get some results back.

I would then move on to seeing what the returned data is -
Code:
TestProgram:
  Do
    Pause 2000
    Do
      Gosub ReadData
    Loop Until w0 = $0304
    Gosub ReadData
    SerTxd( "T=", #w2, TAB, "H=", #w1, CR, LF )
  Loop
That should show temperature (T) and humidity (H) ten times greater than it is, for example T=254 H=345 means 25.4C and 34.5%RH.

If we're getting something which looks realistic it seems we're on the path to having something working.
 

Aries

New Member
Section 8.2 of the AM2320 manual (on the Adafruit link) says
AM2320 sensor I2C address of the (SLAVEADDRESS) 0xB8, on the basis of I2C standard protocol
0xB8 is 0x5C shifted once to the left to accommodate the read/write flag
 

bobladell

New Member
Aries - you are correct, the AM2320 needs a wake up after every read - the question was how to send it. See below on how to do it - I just used the ($B8) as a convenient filler, probably OK with $00.

Hippy - many thanks - I see your code reached the same conclusion as mine.
I also looked at the link you included and not surprised that he found unreliable readings at 70% RH etc as he uses a very caustic solution to create the constant RH test environment. Correct method but the AM2320 / DHTxx etc are damaged by highly aggressive chemical environments - see data sheet section 9, 2.

Pongo - the Arduino must do something differently in handling the low level I2C bus with regard to bit 0, the R/W bit, I'm guessing it inserts the clock bit and level separately in the form address +R/W, as indicated in the AM2320 data sheet, and hence does the shift right to use 7 bit addressing of $5C. Different interpretation of the I2C spec.........?

And the solution is :-

Rich (BB code):
main:
        gosub read_sensors                 ; read the sensors
        pause 1000
        goto main                               ; take next reading

; ****************************
; ***** Read sensor data *****
; ****************************

read_sensors:
        high B.3                                    ; flash green LED
        readtemp C.7, data7                ; read Temperature - DS18B20 - one wire
        low B.3                                     ; end of green LED flash
        sertxd ("DS Temp = ",#data7,CR,LF)
      
read_time:
        hi2csetup i2cmaster, %11010000, i2cslow, i2cbyte    ;Addr $D0
        hi2cin 0,(secs,mins,hours,temp_byte,day,month)
        pause 100
        sertxd ("H = ",#hours,"  Min = ", #mins,CR,LF)     
      
;AM2320 - temp and humidity I2C     
      hi2csetup i2cmaster, $B8, i2cslow, i2cbyte    ;Addr $B8
      hi2cout $B8,($B8)                 ;Wake Up AM2320
      ;pause 1
      hi2cout ($03,$00,$04)            ;Addr+W (=$10), FnCode, StartAddr, No of Reg
        ;pauseus 1600                     ;AM2320 states delay >1.5mS, Arduino code 1600uS - but works without a delay on PICAXE (guess it is inherent in PICAXE constructs)
        hi2cin (b20,b21,b22,b23,b24,b25,b27,b26)          ;Am2320 response Address+R - $03,$04,RHHi,RHLo,THi,TLo,CRCLo,CRCHi
;AM reply
    sertxd ("AM reply = ",#b20,"  FCode = ",#b21,CR,LF)
      
;RH Calc
    sertxd ("RH = ",#b22,"  ",#b23,CR,LF)    ;RH to PC screen

;T Calc
    sertxd ("Temp = ",#b24,"  ",#b25,CR,LF)    ;Temp to PC screen
    
    return
Many thanks guys - as usual it just needs some extra eyes and prompts to get the thoughts straight.

Bob
 
Top