
#REM			           Anemometer Logger 
		 	     Version 5.0.0    24 May 2008 
		 	 		by Gill Adams

	Featuring local display and on board storage of logged data for later transferal to PC.
	It has user selectable display and recording of wind speed in kph or m/s,
	also a user selectable sample time from 1 sec to 60 sec.
#ENDREM		  



	#picaxe 18x	


REM 	Gill NOTE:  This sensor is pulsed 3 times per rev,with rpm to kph conversion factor of 1/5.68

	symbol pulses  = w0		; pulses from rotating head
	symbol clock   = b0		; wind speed as 'clock' pulses for display
	symbol temp_byte = b1		; temp
	symbol dura    = b2		; duration of sample in seconds
	symbol ICn	   = b3		; eeprom IC number
	symbol adrss   = w2		; eeprom address pointer
	symbol wSpeed  = b6		; Wind Speed in kph
	symbol hrs     = b7		; hour of record
	symbol durms   = w4		; duration of sample in miliseconds 
	symbol mins	   = b8		; min of record
	symbol sec     = b9		; sec of record
	symbol lull	   = w5		; 'dura' with no wind 	
	symbol day	   = b10		; 
	symbol date    = b11		;
	symbol lull_10m = w6		; lull count for 10min
	symbol month   = b12		; 
	symbol year	   = b13		;


	EEPROM 0, ("Sat")
	EEPROM 3, ("Sun")
	EEPROM 6, ("Mon")
	EEPROM 9, ("Tue")
	EEPROM 12, ("Wed")
	EEPROM 15, ("Thu")
	EEPROM 18, ("Fri")
	EEPROM 21, ("kph")
	EEPROM 24, ("m/s")
	;eeprom 27 				; duration of sample in seconds'dura' _ saved
	;eeprom 28				; code for speed 'unit' _ saved

;@@@@@@@@@@@@@@@@@@@@@@@
;@@@@ Setup Routine @@@@
;@@@@@@@@@@@@@@@@@@@@@@@


	setint %00000001, %00000001	
Setup:
	high 5				; turn display _ ON
	read 27, dura
	if dura = 0 then			; check for previous saved value
	  dura = 5				; make 5sec the sample duration (default)
	  write 27, dura			; save to eeprom
	endif
	ICn = %10100000			; sets to first eeprom (IC0)
	pulsout 7,10 			; zero the display
	adrss = 0				; sets address pointer to 0
	gosub Beep				; sound "OK"
	
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@
;@@@@ Meter Wind Routine @@@@
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Start:
	lull = 0
Measure:
	low 3					; green LED _ OFF					
	if pin6 = 1 then Adjust		; is 'Adjust sample duration' button_ ON?
	if pin2 = 1 then SetUp_DL	; is 'Down Load Data' button_ ON?
	durms = dura * 1000		; calc miliseconds for sample
	count 7, durms, pulses		; count pulses from anemometer over 'dura' miliseconds 
	if pin0 = 1 then					; is M/s switch_ ON ?
	  pulses = pulses*25/dura*10/36*100/71	; convert pulses to 1/10m/sec	(max 90kph or 25.5m/s) 
	else
	  pulses = pulses*25/dura*10/71		; convert pulses to kph       (max 150kph)
	endif
	let wSpeed = pulses			; extract data variable 'wSpeed' from word variable 'pulses'
	if wSpeed < 2 then NoWind
	if ICn = %10110000 then PrePlay 	; are all eeprom ICs _ full?	
	i2cslave %11010000, i2cslow,i2cbyte	; address the clock IC
	if pin1 = 0 then				; is logging switch_ OFF ?
	  if adrss > 0 then Close
	  goto PrePlay
	endif
	if adrss = 32767 then			; is this eeprom IC _ full up?
	   ICn = ICn + 2				; set for next IC (ICn allocations increment x 2)
	   if ICn = %10110000 then PrePlay 	; are all eeprom ICs _ full up?
	   adrss = 0 
	endif
	high 3					; green LED _ ON showing data is being saved
	if adrss = 0 then DateMe
	readi2c 0, (sec,mins,hrs)		; read clock
	i2cslave ICn, i2cfast,i2cword		; address eeprom IC
	goto Log
;@@@@@@@@@@@@@@@@@@@@@@@@@@
;@@@@ Log Data Routine @@@@
;@@@@@@@@@@@@@@@@@@@@@@@@@@
DateMe:
	readi2c 0, (sec,mins,hrs,day,date,month,year)	; read clock
	i2cslave ICn, i2cfast,i2cword		; address eeprom IC
	writei2c adrss, (day,date) 		; write to eeprom
	adrss = adrss + 2				; set next address
	pause 10
	writei2c adrss, (month,year)		; write to eeprom
	adrss = adrss + 2				; set next address
	pause 10
Log:
	writei2c adrss, (hrs,mins)		; write to eeprom
	adrss = adrss + 2 max 32767		; set next address
	pause 10
	writei2c adrss, (sec,wSpeed)		; write to eeprom
	adrss = adrss + 2 max 32767		; set next address
	goto PrePlay

Close:
	i2cslave ICn, i2cfast,i2cword		; address eeprom IC
	writei2c adrss, ("X","X") 		; write to eeprom
	adrss = adrss + 2				; set next address
	pause 10
	writei2c adrss, ("X","X") 		; write to eeprom
	goto Start

;@@@@@@@@@@@@@@@@@@@@@@@@@
;@@@@ Display Routine @@@@
;@@@@@@@@@@@@@@@@@@@@@@@@@
PrePlay:					; do the "return"/"goto" double shuffle
	gosub Display
	goto Start	
Display: 
	pulsout 7,10			; reset the display
	FOR clock = 1 to wSpeed		; set for a qty of clock pulses = WSpeed
	  pulsout 6,10 			; pulse the display IC's clock pin
	NEXT	 				; next loop 
	return

;@@@@@@@@@@@@@@@@@@@@@@@@@@
;@@@@ DownLoad Routine @@@@
;@@@@@@@@@@@@@@@@@@@@@@@@@@
SetUp_DL:					; download all data to PC
	gosub Beep				; sound "OK"
	high 2				; red LED _ ON
	low 5					; turn display _ OFF
	read 27, dura			; get value in secs
	ICn = %10100000			; set for 1st eeprom IC0
	pulsout 0, 100			; progress lone beep as 1st IC about to be downloaded (7 more to go)
DwnLoad:
	adrss = 0				; set for 1st address
	i2cslave ICn, i2cfast,i2cword	; address eeprom IC
	readi2c adrss, (day,date)			
	adrss = adrss + 2
	readi2c adrss, (month,year)
	adrss = adrss + 2
	gosub BCD_Decimal1
	sertxd (cr,lf,"  ")	
	branch day, (Sat, Sun, Mon, Tue, Wed, Thu, Fri)  ; convert 'day' code to text
Sat:	
	FOR temp_byte = 0 to 2
        read temp_byte, day
        sertxd (day)
      NEXT
      goto MoreDL
Sun:	
	FOR temp_byte = 3 to 5
        read temp_byte, day
        sertxd (day)
      NEXT
      goto MoreDL
Mon:	
	FOR temp_byte = 6 to 8
        read temp_byte, day
        sertxd (day)
      NEXT
      goto MoreDL
Tue:	
	FOR temp_byte = 9 to 11
        read temp_byte, day
        sertxd (day)
      NEXT
      goto MoreDL
Wed:	
	FOR temp_byte = 12 to 14
        read temp_byte, day
        sertxd (day)
      NEXT
      goto MoreDL
Thu:	
	FOR temp_byte = 15 to 17
        read temp_byte, day
        sertxd (day)
      NEXT
      goto MoreDL
Fri:	
	FOR temp_byte = 18 to 20
        read temp_byte, day
        sertxd (day)
      NEXT
      goto MoreDL
      
MoreDL:
	sertxd (" - ",#date,"/",#month,"/0",#year,cr,lf,cr,lf)	; data to PC for Terminal
	;sertxd ("W",#day,"D",#date,"M",#month,"Y",#year)		; data to PC for Windmill logger
	read 28, temp_byte
	branch temp_byte, (KmpH, MtrS)
KmpH:
	DO
	  readi2c adrss, (hrs,mins)
	  adrss = adrss + 2 max 32767	
	  readi2c adrss, (sec,wSpeed)
	  adrss = adrss + 2 max 32767
	  if mins = "X" or wSpeed = "X" then Dl_Over
	  gosub BCD_Decimal2
	  sertxd ("  ",#hrs,":",#mins,":",#sec," .. ",#dura,"sec avg =  ",#wSpeed," kph",cr,lf)	; data to PC for Terminal
	  ;sertxd ("h",#hrs,"m",#mins,"s",#sec,"d",#dura,"w",#wSpeed)	; data to PC for Windmill logger
	LOOP until adrss = 32767	; loop until this IC emptied
	goto NextIC 
MtrS:
	DO
	  readi2c adrss, (hrs,mins)
	  adrss = adrss + 2 max 32767		
	  readi2c adrss, (sec,wSpeed)
	  adrss = adrss + 2 max 32767
	  if mins = "X" or wSpeed = "X" then Dl_Over
	  gosub BCD_Decimal2
	  sertxd ("  ",#hrs,":",#mins,":",#sec," .. ",#dura,"sec avg =  ",#wSpeed," m/s",cr,lf)	; data to PC for Terminal
	  ;sertxd ("h",#hrs,"m",#mins,"s",#sec,"d",#dura,"w",#wSpeed)	; data to PC for Windmill logger
	LOOP until adrss = 32767	; loop until this IC emptied
NextIC:
	ICn = ICn + 2			; set for next IC
	if ICn =  %10110000 then Dl_Over
	temp_byte = ICn + 2
	DO
	  pulsout 0, 200			; progress beeps of the eeprom IC in use
	  pause 100
	  temp_byte = temp_byte - 2
	LOOP until temp_byte => %10100000
	goto DwnLoad
Dl_Over:		
	sertxd (cr,lf," --END--")	; data to PC for Terminal
	;sertxd ("--END--")		; data to PC for Windmill logger
	gosub Beep				; download over _ beep 3x OK's
  	gosub Beep
	gosub Beep
	low 2					; red LED _ OFF
	goto Setup				; and back to reSetup

;@@@@@@@@@@@@@@@@@@@@@@@@@@@@
;@@@@ Conversion Routine @@@@
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@
BCD_Decimal1:
	temp_byte = day & %11110000 / 16 * 10
	day = day & %00001111 + temp_byte
	temp_byte = date & %11110000 / 16 * 10
	date = date & %00001111 + temp_byte
	temp_byte = month & %11110000 / 16 * 10
	month = month & %00001111 + temp_byte
	temp_byte = year & %11110000 / 16 * 10
	year = year & %00001111 + temp_byte
	return
BCD_Decimal2:
	temp_byte = sec & %11110000 / 16 * 10
	sec = sec & %00001111 + temp_byte
	temp_byte = mins & %11110000 / 16 * 10
	mins = mins & %00001111 + temp_byte
	temp_byte = hrs & %11110000 / 16 * 10
	hrs = hrs & %00001111 + temp_byte
	return

;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
;@@@@ Change Metering Unit Routine @@@@
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
interrupt:
	if pin0 = 1 then gosub M_s	; Which unit is selected ?
	if pin0 = 0 then gosub KPH
	return
KPH:
	temp_byte = 0
	write 28, temp_byte
	setint %00000001, %00000001	; set to look for a change back
	return	
M_s:
	temp_byte = 1
	write 28, temp_byte
	setint %00000000, %00000001	; set to look for a change back
	return

;@@@@@@@@@@@@@@@@@@@@@@@@
;@@@@ Sounds Routine @@@@
;@@@@@@@@@@@@@@@@@@@@@@@@
Beep:						; OK
	high 0: pause 80
	low 0: pause 20
	high 0: pause 80			; RoadRunner's bee-beep
	low 0: pause 500
	return

;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
;@@@@ Set Sample Time Routine @@@@
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Adjust:					; adjust the duration of wind speed sample
	gosub Beep
	pulsout 7,10 			; zero the display
	pause 500
	dura = 0
	DO until dura = 60
	  inc dura
	  let wSpeed = dura		; make 'wSpeed' a proxy for 'dura' so to fit with Display code		
	  gosub Display			; display 'dura'
	  pulsout 0, 50			; lone beep sets an audio beat for easy timing of button push
	  pause 800
	LOOP until pin6 = 1		; new duration accepted
	gosub Beep				; sound "OK"
	write 27, dura			; save new value to picaxe eeprom	
	goto Setup

;@@@@@@@@@@@@@@@@@@@@@@@
;@@@@ Sleep Routine @@@@
;@@@@@@@@@@@@@@@@@@@@@@@
NoWind:
	lull_10m = 600 / dura		; calc lull count that makes 10min(600sec)
	if lull = lull_10m then Dozzze	; if no wind for initial 10 min or 1 min thereafter, have 10 min Doze
	inc lull				; advance the lull count by 1
	pause 100
	gosub Display			; go display the wind speed
	goto Measure 
Dozzze:
	low 5					; turn display _ OFF
	sleep 260				; enter sleep mode for 10 minutes
 	let lull = 540 / dura		; set lull to a count = to 9min(540sec)
	high 5				; turn display _ ON
	goto Measure
	

	
	
END






























