This should get you started: BTW the code is losing its indentation when I paste it. Not sure how to correct that!buschlwd wrote:David,
Thanks for posting your project. It looks very promising and it seems to have a lot of interest. Would you mind sharing what python libraries you are using and how you set up your pins to interact with the temperature probe and level switch. I realize this may be a very basic question, but I am new to python. Thanks!
Bill
-----------------------------------------------------------import RPi.GPIO as GPIO
import time
def main():
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(0, GPIO.IN, pull_up_down=GPIO.PUD_OFF)
infloop = 1
switch_down = 0
def switch_pos():
if GPIO.input(switch_down) == 0:
print("Normal")
time.sleep(10)
else
print("Failed. Call in progress")
time.sleep(10)
#This constructs an infinite loop
while infloop == 1:
switch_pos()
if __name__ == '__main__':
main()
If you have any questions I'll do my best to answer.import RPi.GPIO as GPIO
import time
import math
def main():
GPIO.setwarnings(False)
GPIO.cleanup()
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)
GPIO.output(18, GPIO.HIGH)
# This reads the temperature from the DS18B20 and rounds the value to the nearest decimal.
def currtemp():
tfile = open("/sys/bus/w1/devices/28-0000044ac28e/w1_slave")
text = tfile.read()
tfile.close()
secondline = text.split("\n")[1]
temperaturedata = secondline.split(" ")[9]
temperature = float(temperaturedata[2:])
temperature = temperature / 1000
temperature = round(temperature, 1)
return float(temperature)
#Set desired temperature by reading /var/bin/thermostat file
def settemp():
readtemp = open("/var/bin/thermostat", "r")
settemp = readtemp.readline(4)
readtemp.close()
return float(settemp)
# Hold the temperature at the settemp
def holdtemp():
if currtemp() >= settemp():
GPIO.output(18, GPIO.HIGH)
print "State 1",settemp(),"Furnace is off.",currtemp()
time.sleep(10)
else:
if currtemp() + 0.5 <= settemp():
GPIO.output(18, GPIO.LOW)
print "State 2",settemp(),"Furnace is on.",currtemp()
time.sleep(60)
else:
GPIO.output(18, GPIO.HIGH)
print "State 3",settemp(),"Furnace is off.",currtemp()
time.sleep(10)
# This constructs an infinite loop to monitor the temperature
infloop = 1
while infloop == 1 :
holdtemp()
if __name__ == '__main__':
main()
Code: Select all
def heating():
'''
Determine if we need to switch the heater on or off
'''
global set_temp_h, current_temp
if current_temp <= set_temp_h + H:
hvac(True)
return
if current_temp >= set_temp_h - H:
hvac(False)
Code: Select all
def get_sensor_data(ds):
'''
Get the temperatures from one of the DS18B20's.
Test for a proper CRC from the DS18B20 for a YES in the result.
Average the readings for a few times to get a stable return.
'''
avg_tmp = 0.0
x = 1
while ( x <= 5): # 5 readings should do
tfile = open(ds)
text = tfile.read()
tfile.close()
if re.search ("YES", text):
# there is a valid crc in the recording
# strip the rubbish to get to the temperature
temperature_data = text.split()[-1]
temp = float(temperature_data[2:])
temp = (temp / 1000)
if temp < 5 or temp > 33: # one more check
print "\t\tTemp out of range : ", temp
write_log ("Get_sensor_data() Temp out of range : " + str(temp ))
else:
avg_tmp = avg_tmp + temp
x += 1
else:
write_log ("Get_sensor_data() Rcvd corrupted data from sensor\n")
sleep(0.1)
return round(avg_tmp/(x-1), 2) # round to 2 decimal digits
Code: Select all
def write_log(err_str):
'''
Write errors/warnings/messages to a log file.
So we can look at them offline and later.
'''
global set_temp_h, set_temp_c, current_temp
try:
fout = open(logfile_name, "a") # "a" means append
except Exception, e:
# print "\tOutput file open error: %s" % str(e) # while debugging
tstamp = strftime("%d-%m-%Y %H:%M:%S", gmtime())
fout.write (tstamp + " -> " + err_str)
fout.write (str("\n"))
fout.close()
Code: Select all
def mail_alarm(msg, t):
'''
This function emails a message from the raspberry pi to myself.
We also send the IP address, just in case we're going to use
more Pi's later on. This portion can be commented out.
'''
to = 'your email address'
gmail_user = 'Pi_email_address@gmail.com'
gmail_password = 'XXXXX'
smtpserver = smtplib.SMTP('smtp.gmail.com', 587)
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.ehlo
smtpserver.login(gmail_user, gmail_password)
today = datetime.date.today()
arg='ip route list'
p=subprocess.Popen(arg,shell=True,stdout=subprocess.PIPE)
data = p.communicate()
split_data = data[0].split()
ipaddr = split_data[split_data.index('src')+1]
my_msg = 'Message from Pi at IP address %s' % ipaddr +'\n\nWarning: '+ msg + str(t)
msg = MIMEText(my_msg)
msg['Subject'] = 'Msg from Pi on %s' % today.strftime('%b %d %Y')
msg['From'] = gmail_user
msg['To'] = to
smtpserver.sendmail(gmail_user, [to], msg.as_string())
smtpserver.quit()
Code: Select all
<?php
if(isset($_POST["settemp"])) {
$settemp = $_POST["settemp"];
$fp = fopen("/var/bin/thermostat", "w+");
$savestring = $settemp;
fwrite($fp, $savestring);
fclose($fp);
}
?>
Code: Select all
<?php echo exec('python /var/bin/gettemp.py 2>&1'); ?>
Code: Select all
#! /usr/bin/python
# Open the file that we viewed earlier so that python can see what is in it. Replace the serial number as before.
tfile = open("/sys/bus/w1/devices/28-0000044ac28e/w1_slave")
# Read all of the text in the file.
text = tfile.read()
# Close the file now that the text has been read.
tfile.close()
# Split the text with new lines (\n) and select the second line.
secondline = text.split("\n")[1]
# Split the line into words, referring to the spaces, and select the 10th word (counting from 0).
temperaturedata = secondline.split(" ")[9]
# The first two characters are "t=", so get rid of those and convert the temperature from a string to a number.
temperature = float(temperaturedata[2:])
# Put the decimal point in the right place and display it.
temperature = temperature / 1000
print temperature
Code: Select all
<form name="termostat" method="post" class="label-top" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<div>
<label for="settemp" class="inline">Temperature set at</label>
<select name="settemp" id="settemp" onChange="this.form.submit()">
<option value=null SELECTED><?php $curSet = file_get_contents('/var/bin/thermostat'); echo $curSet; ?> °C </option>
<option value="21.5">High(21.5°C)</option>
<option value="20.0">20°C</option>
<option value="19.5">Home(19.5°C)</option>
<option value="19.0">19°C</option>
<option value="18.5">18.5°C</option>
<option value="15.5">15.5°C</option>
<option value="15.0">Away(15°C)</option>
<option value="14.5">14.5°C</option>
<option value="10.0">Low(10°C)</option>
</select>
</div>
</form>
Code: Select all
def heating():
'''
Determine if we need to switch the heater on or off.
While the temperature is within the
set_temp_h +/- hysteresis (H) range, the current system
state stays unchanged.
'''
if current_temp >= set_temp_h + H:
# print "stop furnace", current_temp, set_temp_h + H
hvac(False)
if current_temp <= set_temp_h - H:
# print "start furnace", current_temp, set_temp_h - H
hvac(True)
Code: Select all
def cooling():
'''
Determine if we need to turn the cooling on or off.
While the temperature is within the
set_temp_c +/- hysteresis (H) range, the current system
state stays unchanged.
'''
if current_temp <= set_temp_c - H:
# print "stop A/C", current_temp, set_temp_c - H
hvac(False)
if current_temp >= set_temp_c + H:
# print "start A/C", current_temp, set_temp_c + H
hvac(True)
I will be using the web stuff that David is using for his project heavily and sharing with us, so keep an eye on that too.Automatic Thermostat
David, this is an interesting board for a great price. Where did you find this?onepoint21 wrote:These are the temperature sensors that I will be mounting (in some fashion) to the wall. They cost about $3 per board. Very small and easy to hide.
David, I got it working on my machine. I had one issue to deal with, I needed to chmod the data file before I got it working (newby!). Thanks a bunch, this will help me to get started on php and I will now try to extend your program and incorporate it in my own program. Stay tuned on developments in my post (Automatic Thermostat).Paul Versteeg wrote:Hey David,
Thank you very much for the web stuff. I'm a real nuby on PHP and HTML, but I will take a look at what you've done and will try to understand it and see if I can implement it as well. I'll keep you posted.
Tks,
Paul
Hi Paul, This board was purchased on ebay. (http://www.ebay.ca/itm/DS18B20-temperat ... 1247wt_952)Paul Versteeg wrote:David, this is an interesting board for a great price. Where did you find this?onepoint21 wrote:These are the temperature sensors that I will be mounting (in some fashion) to the wall. They cost about $3 per board. Very small and easy to hide.
This board also has some more components beside the DS and the resistor. I'd like to know what they are.
Code: Select all
#!/usr/bin/python
import RPi.GPIO as GPIO
import time
def ReadCpuTemperature():
file= open("/sys/class/thermal/thermal_zone0/temp","r")
string = file.readline()
file.close()
cputemp = float(string)/1000.0
return cputemp
def ReadSensor( SensorId):
while(1):
fname = "/sys/bus/w1/devices/" + SensorId + "/w1_slave"
tfile = open(fname)
text = tfile.read()
tfile.close()
firstline = text.split("\n")[0]
crc_check = text.split("crc=")[1]
crc_check = crc_check.split(" ")[1]
if crc_check.find("YES")>=0:
break
secondline = text.split("\n")[1]
temperaturedata = secondline.split(" ")[9]
temperature = float(temperaturedata[2:])
temperature = temperature / 1000.0
# if temperature<0:
#print text
return temperature
GPIO.setwarnings(False)
# set pin 16 et 18 output
GPIO.setmode(GPIO.BOARD)
#GPIO.setup(16,GPIO.OUT)
GPIO.setup(18,GPIO.OUT)
#GPIO.output(16,GPIO.LOW)
#GPIO.output(18,GPIO.LOW)
target=4.0
histeresys=0.5
heater_on=True
while True:
time_string = time.strftime("%d%b%Y %H:%M:%S",time.localtime())
th_cpu = ReadCpuTemperature()
th_main_box = ReadSensor("28-00000457ecaa")
th_cam_box = ReadSensor("28-0000045d387d")
th_outside = ReadSensor("28-000004575419")
th_pond1 = ReadSensor("28-000004575f0a")
th_pond2 = ReadSensor("28-000004583355")
if th_pond1 < th_pond2:
th_min=th_pond1
else:
th_min=th_pond2
if th_min > (target+histeresys):
heater_on = False
if th_min < (target-histeresys):
heater_on = True
if heater_on:
GPIO.output(18,GPIO.HIGH)
else:
GPIO.output(18,GPIO.LOW)
print "{0} T('C) CPU:{1:.0f} Box:{2:.1f} Cam:{3:.1f} Out:{4:.1f} Pond1:{5:.1f} Pond2:{6:.1f} SetP:{7} Heater:{8}" .format(time_string,th_cpu,th_main_box,th_cam_box,th_outside,th_pond1,th_pond2,target,heater_on)
There is quite a lot of information about w1 interfaces and the cabling required if you Google for it. The major recommendation is to use Cat-5 cable. Don't use ordinary cable, like telephone cable. The distance can be 100 meters or more, the topology should not be a "star" if possible.oxfletch wrote:Any idea what distances these temp sensors can run over? What I would love to do is install one in each room in the house, and run them back over twisted pair cable back to a central Raspberry PI
Very very cool. I wouldn't have ever figured that out. Definitely implementing this.danjperron wrote:You should check the crc of the ds1820 sensor. I just finish to hook up 5 sensors on my pond heater system and I found out that sometimes sensors gives bad results. When I looked at the returned data, I found out that every time the temperature is wrong , the crc is also not ok. (data return is all ones). So I modified the read the sensor functions and implements the crc check. We just need to look for the string 'YES' at the first row.