RHT03 Temp Hum Sensor Code
CelticLord
Posts: 50
Found code that works with the RHT03 / DHT22 and the Propeller THANKS TO Tom Crawford........
{Demo PASM Driver for AOSONG Am2303 / RHT03 / DHT22} CON _clkmode = xtal1 + pll1x 'clock mode _xinfreq = 5_000_000 '* crystal frequency 'ClkFreq is 5 MHz to reduce power am2303pin = 12 'am2303 pin 'Define the LED Led = 16 VAR byte Debug, cog long MyPar[6] 'these variables are associated with the am2303 and its cog word RH, DegreesC, DegreesF 'relative humidity, Temperatures byte Checksum, sumcheck 'returned checksum, calculated checksum byte Am2303Data[5] 'the five bytes we read byte Am2303Flag 'not equal to zero says read 2303, = 0 says data available OBJ pst : "parallax serial terminal" PUB main pst.Start (9600) 'start up ser terminal at 9600 pst.str(String("hello, world ")) 'runs in cog 1 pst.NewLine waitcnt(clkfreq/10+cnt) MyPar := @Am2303Data 'where to return the five bytes of data MyPar[1] := Am2303Pin 'which pin to look at MyPar[2] := @Am2303Flag 'flag that says start up the am2303 MyPar[3] := (clkfreq/1_000_000) * 50 'clock tics in 50 useconds ' cog := cognew(@Am2303Cog, @MyPar) 'start up the 2303 reader cog pst.str(String("Am2303 Cog: ")) ' pst.hex(Cog,1) pst.NewLine repeat 'forever waitcnt((clkfreq*10) + cnt) 'wait ten seconds Am2303Flag := $55 'tell the temp cog to begin waitcnt(clkfreq/200 + cnt) 'power down about 5 msec repeat while Am2303Flag <> 0 'and wait here until data are returned RH.byte[0] := Am2303Data[1] 'sort out returned data and calculate checksum sumcheck := RH.byte[0] RH.byte[1] := Am2303Data[0] sumcheck := sumcheck + RH.byte[1] DegreesC.byte[0] := Am2303Data[3] sumcheck := sumcheck + DegreesC.byte[0] DegreesC.byte[1] := Am2303Data[2] sumcheck := sumcheck + DegreesC.byte[1] Checksum := Am2303Data[4] 'checksum check if checksum <> sumcheck Pst.str(string("Checksum Error: Calculated: ")) pst.hex(Sumcheck,2) Pst.str(string(" Received: ")) pst.hex(Checksum,2) pst.newline pst.str(string("Raw Temp Hex: ")) pst.hex(DegreesC,4) pst.str(string(" DegreesC: ")) if (DegreesC & $8000) == 0 '0 degreesC or higher pst.dec(DegreesC/10) 'integer part pst.char(".") pst.dec(DegreesC//10) 'tenths DegreesF := ((DegreesC * 9) / 5) + 320 'degrees F times 10 DegreesF := (DegreesF + 5) / 10 'rounded pst.str(String(" DegreesF: ")) pst.dec(DegreesF) else 'below 0 degreesC DegreesC := DegreesC & $7FFF 'drop the sign bit, leaving magnitude pst.char("-") 'minus sign pst.dec(DegreesC/10) 'integer part pst.char(".") pst.dec(DegreesC//10) 'tenths DegreesF := 320 - ((DegreesC * 9) / 5) DegreesF := (DegreesF + 5) / 10 'rounded pst.str(String(" DegreesF: ")) pst.dec(DegreesF) pst.str(string(" Raw Humidity Hex: ")) pst.hex(RH,4) RH := (RH + 5) / 10 'round (up or down) and divide by 10 Pst.str(string(" Relative Humidity: ")) pst.dec(RH) pst.newline dat 'this is the cog that talks to the Am2303 Am2303Cog org 0 mov AdPar,Par 'get the address of input parameters rdlong AdData, AdPar 'where to store the data add AdPar, #4 'to pin number rdlong AmPin, AdPar 'get it add AdPar, #4 'to flag address rdlong AdFlag, AdPar 'get it add AdPar, #4 'to 50 usec count rdlong Usec50, AdPar 'and get it mov AmMask, #1 'form the mask for dira, outa shl AmMask, AmPin 'by shifting appropriately mov S1Mask, #1 'make the two scope sync masks shl S1Mask, #14 or dira, S1Mask 'and enable the pins mov S2Mask, #1 shl S2Mask, #15 or dira, S2Mask top rdbyte MyFlag, AdFlag 'look at the START flag test MyFlag, #$FF wz 'see if any bits set if_nz jmp #start 'if so, go start the 2303 mov count2, TwoK 'otherwise set up to wait 100 millisec top0 mov count1, Usec50 add count1, cnt waitcnt count1, #0 'waiting in low power mode djnz count2, #top0 jmp #top 'continue to wait start mov count2, #20 '20 times 50 usec is 1 msec or outa, AmMask 'dont glitch pin low or dira, AmMask 'drive pin high andn outa, AmMask 'now low. This starts the am2303 in 1 msec loop1 mov count1, Usec50 '50 usec worth of clocks add count1, cnt 'plus current time waitcnt count1, #0 'wait for it djnz count2, #loop1 'use up 1 msec or outa, AmMask 'drive the pin high andn dira, AmMask 'and get off the bus waitpeq Zero, AmMask 'wait for Am2303 to take it low waitpeq AmMask, AmMask 'and then back hi mov CurAd, AdData 'where to store the first byte mov Bytes, #5 'we will store five bytes waitpeq Zero, AmMask 'and back low prior to first data bit ' 'we are now in the low time prior to first data bit BytLp mov Bits, #8 'eight bits per byte mov DByte, #0 'nice empty accumulator BitLp shl DByte, #1 'shift what we have so far or outa, S1Mask 'high while waiting for a bit to complete waitpeq AmMask, AmMask 'wait for the beginning of the pulse mov BCnt, cnt 'count at beginning of pulse waitpeq Zero, AmMask 'wait for pulse to go away mov ECnt, cnt 'count at end of pulse andn outa, S1Mask 'bit is complete sub ECnt, BCnt 'compute length of positive pulse cmp ECnt, Usec50 wc if_c jmp #BitLp1 'jump if length less than 50 use or DByte, #1 'set a one or outa, S2Mask 'scope pulse nop andn outa, S2Mask BitLp1 djnz Bits, #BitLp 'eight bits wrbyte DByte, CurAd 'save this byte add CurAd, #1 'to next byte djnz Bytes, #BytLp 'five bytes wrbyte Zero, AdFlag 'we are done, zero the flag jmp #top 'and go monitor the flag bit again forever Zero long 0 'zero value for waitpeq TwoK long 2_000 'two thousand (times 50 usec yields 100 msec) AdPar RES 'the paramemters address AdData RES 'the address of the first byte of data CurAd RES 'the address to store next byte of data AdFlag RES 'Address of the flag byte AmPin RES 'the actual pin number AmMask RES 'single bit corresponding to the Am2303 pin Usec50 RES 'clock tics in 50 usec count1 RES 'used for waitcnt's count2 RES 'times out one msec MyFlag RES 'my copy of the flag S1Mask RES 'scope syncs S2Mask RES BCnt RES 'count at beginning of high pulse ECnt RES 'count at end of high pulse Bits RES 'counts bits in each byte Bytes RES 'counts bytes of data DByte RES 'where we accumulate each byte of data