' ***********************************************************************
' *                    < HOLOSOUND - Hardware V3.0 >                    *
' *                               <DIANA>                               *
' *                  Hybrid computer section front-end                  *
' *             Source code for Basic Stamp microcontrollers            *
' *            used for velocity derivation in channels X,Y,Z           *
' *                         ADC Channels 4, 5, 6                        *
' *                      by Dr.Godfried-Willem Raes                     *
' *                       filename: FRQ2PWM.BS1                         *
' ***********************************************************************

' 04.09.1995: first experimental design and testing session
'             Note: BSAVE in  this code, anywhere, causes the Stamp-editor
'             to write a *.OBJ file to disk. This file, always exactly
'             256 bytes long, is the complete content (memory image) of 
'             the EEPROM. This file should be used for quick downloads.
'             The editor saves the file to disk as CODE.OBJ
'             It should be renamed! (maintain the *.OBJ extention)
' 05.09.1995: further refinements: define pin 6 as input!
'             Once the program is load into the EEPROM, it remains there
'             until it is overwritten externally. Thus we do not need a
'             nap-feature except for power saving during operation or
'             for guaranteeing start-up after complete power-up conditions.
'             There is a performance penalty for every single instruction
'             that is not strictly needed in the program loop.
'             Execution speed: ca. 2000 instructions per second
'             = ca. 0.5ms per instruction
'             This program has about 30 instructions, and thus its runtime
'             should be estimated in  the order of 15ms + the time of the
'             pulses to be measured + 5ms for the PWM burst!
'             The fastest pulses to be expected are 500Hz or 2ms.
'             This brings the maximum sampling rate to 22ms or ca.45s/s,
'             witch is in accordance with Von Baer and Leman (50-30ms).
'             However, as the movement velocity goes down, the sampling rate
'             sinks, since the pulse-lenght is inverse proportional to the 
'             speed of the movements.
'             The compiled object-file takes no more than 45 bytes.
' 17.09.1995: Execution speed can be doubled at the detriment of precision
'             Read only the lenght of the positive pulse.
'             This is f/2, so the numeric result should be doubled.
' 23.09.1995: <DIANA> pc-board design session.
'             For board lay-out reasons, we changed the pin definitions and 
'             functions.
'             Now PWM output goes to pin5
'             Puls-input goes to     pin0
'             Grounded:              pin1, pin4
' 29.10.1995: <DIANA> board fully populated & tested.
' 03.10.1996: code slightly revised. (ordering of instructions)
'             We need some form of noise filtering!
'             Now we filter out values that are impossibly high.
'             Integration still to be added...

' Hardware description:
' Three BASIC Stamps in <DIANA> serve as frequency meter to pwm converters.
' Their outputs are DC-voltages to be fed (after buffering) to ADC-converter 
' channels (ARCOM board IO-tech or Analogic). 
' They accept pulse (from a comparator) input through their pin 0, and output 
' pwm-signals from their pin 5's. Resolution is <= 8 bits.
' Pin 6 should be connected to an RC-circuit, for integration:
'              4.7kOhm- 0.47mF gives 2.2 ms RC time   Icmax=1mA
' ******       10kOhm - 0.47mF gives 4.4 ms RC = 1 PWM burst      OK <DIANA>
'              10kOhm - 1 mF gives 10ms RC-time
'             100kOhm - 100nF gives 10ms RC-time as well Icmax=50microAmps
'              10kOhm - 10mF gives an 0.1s RC-time    Icmax=0.5mA
'             100kOhm - 1 mF gives the same result.   Icmax=50microamps
' The dc-signal should be buffered. The DC range is 0-5V        
' With this code the transfer characteristic is 51Hz/V, not very
' different from the 55Hz/V in the analog computer used for BOM V2.
' Conversion speed is now a function of the input signal!
' Cancelled: ********************************
' Refinements:
'       pin 5 is used as a power-on sensor.
'       If pin 5 goes 0, then the Stamp takes a nap.
'       Under normal working conditions the controller gets power via
'       its pin for Vin. When this voltage dies, it goes to sleep mode
'       and is powered from a 1Farad cap connected to Vdd.
'       If this is still uncomfortable, we could also use an on board
'       lithium cell.

'    input 5            ' input pin napping: if 0 nap occurs          
'    input 6            ' pwm-output pin! This to reduce leakage.
'    input 7            ' input pin for puls-time measurement
'StartUp:
'    IF pin5 = 0 THEN slaap
' *******************************************

Start:
	   input 0            ' input pin for pulse-time measurement
	   input 1            ' grounded on PC-board
	   input 2            ' not used
	   input 3            ' not used
	   input 4            ' grounded on PC-board
	   input 5            ' PWM-output pin!. Defined as IN to reduce leaks.
	   input 6            ' not used
	   input 7            ' not used

Frq:    
	pulsin 0,1,w1      ' Read positive-going pulse on pin 0.
	IF w1 < 50 then Frq 
	w1 = w1/10         ' more precise alternative - 100microsec. units  
	
	pulsin 0,0,w2      ' Read negative-going pulse on pin 0.
	IF w2 < 50 then Frq  
			   ' These readings return 16bit values:0-&HFFFF
			   ' One bit equals 10microseconds.
			   ' A full period is w1+w2, but since we should
			   ' never exceed &HFFFF, we scale the values down: 
	w2 = w2/10         ' =0.1ms
			   ' For true binary calculation we could also
			   ' do w1 = w1/2      20microsecond increments
			   '    w2 = w2/2
			   '    w3 = w1+w2
			   '    w4 = $FFFF / w3   range= 0 - $FFFF  16bits
			   '    w4 = w4 / $100    range= 0-255       8bits
	w3 = w1 + w2       ' time for a full period (averaged over 2 cycles)
			   ' w3 is expressed in 0.1ms units.
	w4 = 10000 / w3 max 255    ' w4 is the frequency expressed in Hz
			   ' The microcontroller does not need a protection
			   ' against divide through zero-errors!
			   ' If w3 is zero, w4 is evaluated as zero as well.
			   ' Test 03.09.1995:          Meting 22.09.95:
			   ' fi= 0    ->  w4= 0
			   ' fi= 8Hz  ->  w4= 8       -> 170mV
			   ' fi= 82Hz ->  w4= 81      -> 1.61V
			   ' fi= 820Hz -> w4=833      -> 5.04V
			   ' we here limited to f <= 255Hz (19.5mV/Hz)
	pwm 5,w4,1         ' output this as a number (1) of pwm bursts
			   ' each burst takes about 5 ms.
	'debug #w4         ' used for measurement and test purposes. 
	goto Frq
'Slaap:
'    nap 7              ' naps for 2304ms - power consumption is thus
'                 ' reduced to 20microamps.
'    goto StartUp
	bsave              ' use once to generate an object file
	
'note: (1) a true 16-bit version could be made by using two pwm output pins
'      One pin would output the LSB value (8 bit) as a 0-5V DC range
'      the other pin, the MSB value (8bit) as a 0-5V range
'      An Op-amp summer/buffer could be used to recombine the outputs.
'      (2) the sampling rate for slow movements can be doubled, by using
'      two BS1 processors, one performing PULSIN 6,0,w1, the other
'      PULSIN 6,1,w1. The outputs of both can than be buffered and summed 
'      using a quad opamp configuration (2x buffer, mixer, inverter).
