'm168-test-capacitor-rc-timing-direct.bas
'  Direct read capacitive humidity sensor from Micro controller.
'  which reduces the parts costs.  The basic capacitive sensors start
'  at about $3.50 while the voltage or freq out tend to start at $15
'  and run to over $30.  My favorite is the SHT11 and SHT75 but they
'  start at $30.    The same approach can be used
'  to sense change in capacitance for other circuits
'  such as strain gauges.
'
'  This design provides easy field program calibration capability through
'  serial line which the other sensors do not.   Simply send command to
'  calibrate and current reading near the sensor.  It will compare that to
'  current values and save reading in eprom.  Allows for easy field
'  calibaration.
'
'  Tested on Mega168 but only used 18% of program space so should run
'  in 4K and 8K devices just fine. Probably better implemented with
'  a AVRTiny which could be mounted right on the sensor and then hold
'  1 wire conversation back to master controller.
'
'
' HCH sensor typical response curve 298Pf at 0%RH upto 358pf @ 100%. Interestingly
' got numbers very close to this range from loop counter with 10M resistor.
' http://www.honeywell-sensor.com.cn/prodinfo/sensor_humidity_moisture/datasheet/HCH-1000.pdf
' http://mouser.com/ProductDetail/Honeywell/HCH-1000-002/?qs=yJVtgANCw01Gp3IHDXhPcA%3d%3d
'
'

' ******
' **** Enhancments ***
' ******
' TODO:  convert this to word array and use for loop to average.
' TODO: Add second array to average the averages to reduce hysteris.
' TODO: Add inbound button to run average of 33% salt solution and store
'  in non volatile memory.  second button for 76% or 100% solution.
'  change calculator to use NV memory to retain.
' TODO: Add pin 1..7 to allow any additional pins on port D to
'  to act as readers.  Allow these to be multi-plexed  by passing
'  in parm to function.  Need to figure out how to pad pind.x as parm.
' TODO: Convert all to word calculations and scale up by 100 to retain decimals
' that way eliminate need for floating point at all.
' TODO: Add 1 leg of temp sensor back into the solution to allow temperature
'  compensation.



'$regfile = "m64def.dat"
$regfile = "m16def.dat"
$crystal = 8000000
$hwstack = 64                                               ' default use 32 for the hardware stack
$swstack = 60                                               ' default use 10 for the SW stack
$framesize = 80                                             ' default use 40 for the frame space


dim tbyte as  Byte
Dim tInt as integer
dim tfloat as single
dim tsingle as single
dim tlong as long
dim tword as word
dim tword1 as word
dim tword2 as word
dim tword3 as word
dim tword4 as word
dim tword5 as word
dim tword6 as word



dim r_dif as single
dim p_dif as single
dim rdif_per_perc as single


Open "comd.1:9600,8,N,1,inverted" For Output As #1
Open "comd.0:9600,8,N,1,inverted" For Input As #2


Const bon = 1
Const boff = 0

Config Portd.5 = Output
Config Portd.4 = input
config portd.6 = output

rc_charge alias portd.5
rc_read alias pind.4
led alias portd.6
rc_charge = boff


'const hi_r = 1225 ' count reading at high humidity
'const hi_p = 100  ' percentage reading taken at
const hi_r = 1097 ' count reading at high humidity
const hi_p = 75.3  ' percentage reading taken at


'const lo_r = 1045 ' count reading at low humidity
'const lo_p = 33   ' RH percentage at low humidity reading
const lo_r = 1063 ' count reading at low humidity
const lo_p = 44   ' RH percentage at low humidity reading


const lo_no_sens = 400 ' if reading is lower than this assume no sensor present
                        ' no sensor is typically about 19

r_dif =   hi_r - lo_r   '177
p_dif =   hi_p - lo_p   ' 65
rdif_per_perc =  r_dif / p_dif ' 177/65 = 2.73


print #1, "m168-test-capacitor-rc-timing-direct.bas"


'TODO:  Take the last 5 average readings
' and averge them 5 times to get a lower
' hysteris value.

Dim tlongx as word
Dim i as byte

Do
  tlongx = 0
  ' Take multiple readings in a row and average them.
  ' for any single reading.
  for i = 1 to 12
    reset rc_charge
    Bitwait rc_read, reset  ' wait until read low
    waitms 3  ' Finish waiting until we know fully discharged.
                ' could also change IO state of input pin and set to
                ' low to make sure it is off
                ' TODO: Make this so 1/3 of minimum sensor read
    tword = 0
    set led
    set rc_charge
    while rc_read < bon ' Manual loop to see how long it takes to
      tword = tword + 1   ' Charge the capacitor
    wend
    reset rc_charge
    reset led
    tlongx = tlongx + tword
  next i
  tlongx = tlongx / 12


    print #1, "tword="; tlongx;

    'calculate average of last 4 readings

    tlong = tlongx + tword1
    tlong = tlong + tword2
    tlong = tlong + tword3
    tlong = tlong + tword4
    tlong = tlong + tword5
    tlong = tlong + tword6

    tlong = tlong / 7
    print #1, " avg=";tlong;

    tword6 = tword5
    tword5 = tword4
    tword4 = tword3
    tword3 = tword2
    tword2 = tword1
    tword1 = tlongx

    'Convert Avg reading to Percentage
    dim dlow as single
    dim dmult as single
    dim tperc as single
    dlow = tlong - lo_r
    '  how far are we above low calibration reading
    tfloat = tlong
    dmult = dlow / rdif_per_perc
    '  how many units of percentage dose delta reading work out to.
    tperc = lo_p + dmult

    print #1, " % avg=";Fusing(tperc , "-###.#")


  Waitms 500



Loop


