With the wife out-of-town on business, I've been able to spend some time experimenting with the circuitry I'll need to construct the capacitive humidity sensor.
Previously, I had constructed a prototype based upon schematics I found on the Internet for an Arduino weather station, which used the same HCH-1000 sensor. I tested the circuit in KTechlab and it seemed to simulate very well. However, in my rush to produce the circuit, I made some mistakes while adapting it to a much smaller SMD populated circuit, and ended up burning my finger quite badly during testing. It's a long story, but, needless to say, I've relearned my lesson. Whenever you are building a circuit, it's always better to have a full understanding of what's happening within that circuit rather than just assembling it from a schematic.
With this in mind, I spent much of yesterday re-immersing myself in the properties of our good friend the 555 timing circuit. About two or three years ago, I had used the 555 to build a heterodyning ultrasonic bat detector, but I haven't worked much with them since and forgot most of the basics. Specifically, I'm referring to astable operations in which the 555 is configured with two resistors and a capacitor to create a multivibrator (i.e. oscillator). Adjusting either of the two resistors or the capacitor will change the nature of the oscillation frequency. There are a few useful equations which can be used to determine the outcomes of different combinations of resistors and capacitors, which I have captured in an annotated Python script called T555.py.
# -*- coding: utf-8 -*-
"""
Created on Fri Aug 9 12:20:02 2013
@author: dan
"""
# capacitance is in Farads and resistance is Ohms
#Calculates the charging time of the capacitor (C) for resistor a (Ra) and resistor b (Rb).
def chT(Ra,Rb,C):
cT = 0.693*(Ra+Rb)*C
return cT
#Calculates the capacitor discharge time
def dT(Rb,C):
diT = 0.693*Rb*C
return diT
#Calculates the time for both capacitor charge and discharge
def TT(Ra,Rb,C):
cT = chT(Ra,Rb,C)
diT = dT(Rb,C)
T = cT + diT
return T
# Calculates the oscillation frequency output produced by Ra, Rb, and C
def Freq(Ra,Rb,C):
O = 1.44/((Ra+(2*Rb))*C)
return O
#Calculates the duty cycle produced by the resistors and capacitors, which is a proportion comparing the charge time to the discharge time.
def dC(Ra,Rb):
D = float(Rb)/(Ra+(2*Rb))
return D
#Calculates the combined value of both resistors based upon the known oscillation and capacitance
def AB2(O,C):
ab2 = 1.44/(C*O)
return ab2
# Calculates the individual values of Ra and Rb based upon the known duty cycle, oscillation, and capacitance
def AB(D,O,C):
ab2 = 1.44/(C*O)
Rb = ab2*D
Ra = ab2-(Rb*2)
print "Resistor A: " + str(format(int(Ra),","))
print "Resistor B: " + str(format(int(Rb),","))
# Reports calculations for charge time, discharge time, total time, frequency, and duty cycle.
def rt(Ra,Rb,C):
cT = chT(Ra,Rb,C)
diT = dT(Rb,C)
T = cT + diT
O = 1.44/((Ra+(2*Rb))*C)
D = float(Rb)/(Ra+(2*Rb))
print "Charge time (seconds): " + str(cT)
print "Discharge time (seconds): " + str(diT)
print "Total time (seconds): " + str(T)
print "Frequency (Cycles per Second): " + str(O)
print "Duty cycle: " + str(D)
In addition to the above script, I also wrote a script called Farads.py that gives you easy conversions between commonly used Farad units. I did this because I loath making these conversions.
# -*- coding: utf-8 -*-
"""
Created on Fri Aug 9 13:57:53 2013
@author: dan
"""
def cF(number,faradunit):
if faradunit == "F":
F = number
elif faradunit == "mF":
F = float(number)/1000
elif faradunit == "uF":
F = float(number)/1000000
elif faradunit == "nF":
F = float(number)/1000000000
elif faradunit == "pF":
F = float(number)/1000000000000
else:
print "faradunit must be F, mF, uF, nF, or pF"
mF = F*1000
uF = F*1000000
nF = F*1000000000
pF = F*1000000000000
print "farads: " + str(format(F,",")) + " F"
print "millifarads: " + str(format(mF,",")) + " mF"
print "microfarads: " + str(format(uF,",")) + " uF"
print "nanofarads: " + str(format(nF,",")) + " nF"
print "picofarads: " + str(format(pF,",")) + " pF"
Once these scripts were placed in my "site-packages" folder, I was able to use the following workflow:
At 55% relative humidity, the HCH-1000 has a normal capacitance of 330 pico Farads. Let's say that I want to measure the capacitance of the HCH-1000 500 times per second (I still haven't figured out what the ideal measurement frequency would be for Arduino, so this is just a place holder) and a duty cycle of 0.50. In python I would do the following:
>>> import Farads as F
>>> F.cF(330,"pF")
the program would then return:
farads: 3.3e-10 F
millifarads: 3.3e-07 mF
microfarads: 0.00033 uF
nanofarads: 0.33 nF
picofarads: 330.0 pF
next, I type:
>>> import T555 as T
>>> T.AB(0.49,500,3.3e-10)
note that I use 0.49 and not 0.50. This is because 0.50 is and ideal number that produces an Ra value of 0.
The results are:
Resistor A: 174,545
Resistor B: 4,276,363
Now, using a
table for commonly used resistor values, I see that 180,000 and 4,300,000 Ohm resistors are likely to exist. It may be likely that these slight changes to the resistance values will have little effect, but I can test is to be sure:
>>> T.rt(180000,4300000,3.3e-10)
Which returns:
Charge time (seconds): 0.0010245312
Discharge time (seconds): 0.000983367
Total time (seconds): 0.0020078982
Frequency (Cycles per Second):
496.
997307931
Duty cycle: 0
.489749430524
This close enough. I'll write more later, but I wanted to note one more thing. Yesterday, I checked the status of a container of sugar water I had placed in the beehive the day before to feed the bees. It was completely empty! They had managed to drink more than a gallon of 1:1 sugar/water solution in less than 24 hours. In response, I created a new batch of 2:1 sugar/water solution and placed it in the hive yesterday evening. I'll be interested in checking again today to see how far they've gotten with that batch.