JoshD086
Posts: 4
Joined: Tue Sep 11, 2018 2:47 am

Need a little help/input on controller.

Thu Sep 13, 2018 6:31 am

Hello all, i am pretty new to raspberry pi and python language, i studied C and C++ but that was years ago before i decided on a different profession, and i am super rusty. I'm not 100% sure that this is posted in the correct section, if not, please point me in the right direction.

I am trying to build a controller that will turn a system off in part or whole depending on a couple temp inputs. It will be for a walk in produce storage area/fridge and will be controlling a standard ac unit. I think I have got the basics figured out, but need to fine tune some things. The while loop is where most of the trouble is, I think. I would like to be able to keep the temp readings printing while the script is running but need the relays to continue to operate in the states programmed per those readings even if “suspended” due to being below threshold. Right now, it’s all or nothing. If there is a better/cleaner way to achieve this, i am all for it. I would also like to figure out how to make the script run for maybe 15-30 minutes so long as the temp readings are correct, and then run every hour, or maybe its better to just have it run and just sleep for a given time. I just don’t want rapid on/off cycles like I’m getting now. Any help or insight is greatly appreciated.

Here is the code:

Code: Select all


#!/usr/bin/env python3

import os
import glob
import time
from time import sleep
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
#GPIO Pins: 22 fan_mains, 24 compressor_mains
pinList = [22,24]
for i in pinList:
    GPIO.setup(i, GPIO.OUT)
    GPIO.output(i, GPIO.HIGH)

os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

base_dir='/sys/bus/w1/devices/'
device_folder_1=glob.glob(base_dir + '28-041720f964ff')[0]
device_folder_2=glob.glob(base_dir + '28-041720f612ff')[0]
device_folder_3=glob.glob(base_dir + '28-0417211dadff')[0]
device_file_1=device_folder_1 + '/w1_slave'
device_file_2=device_folder_2 + '/w1_slave'
device_file_3=device_folder_3 + '/w1_slave'
set_temp = 50.0
ice_temp = 32.0

def read_temp_raw_1():
    f = open(device_file_1, 'r')
    lines = f.readlines()
    f.close()
    return lines

def read_temp_1():
    lines = read_temp_raw_1()
    while lines[0].strip() [-3:] != 'YES':
        time.sleep(10.0)
        lines = read_temp_raw_1()
    equals_pos = lines[1].find('t=')
    if equals_pos != -1:
        temp_string = lines[1][equals_pos+2:]
        temp_f_1= float(temp_string) / 1000 *9.0 / 5.0 + 32.0
        return temp_f_1

def read_temp_raw_2():
    f = open(device_file_2, 'r')
    lines = f.readlines()
    f.close()
    return lines

def read_temp_2():
    lines = read_temp_raw_2()
    while lines[0].strip() [-3:] != 'YES':
        time.sleep(10.0)
        lines = read_temp_raw_2()
    equals_pos = lines[1].find('t=')
    if equals_pos != -1:
        temp_string = lines[1][equals_pos+2:]
        temp_f_2= float(temp_string) / 1000 *9.0 / 5.0 + 32.0
        return temp_f_2

def read_temp_raw_3():
    f = open(device_file_3, 'r')
    lines = f.readlines()
    f.close()
    return lines

def read_temp_3():
    lines = read_temp_raw_3()
    while lines[0].strip() [-3:] != 'YES':
        time.sleep(10.0)
        lines = read_temp_raw_3()
    equals_pos = lines[1].find('t=')
    if equals_pos != -1:
        temp_string = lines[1][equals_pos+2:]
        temp_f_3= float(temp_string) / 1000 *9.0 / 5.0 + 32.0
        return temp_f_3
    
    
while True:
    print ("Interior Temp:", round(read_temp_1(), 1), "coil:", round(read_temp_2(), 1), "compressor:", round(read_temp_3(),1))
    if read_temp_2()>= ice_temp:
        GPIO.output(22, GPIO.HIGH)
        time.sleep(120)
       
    else:
       GPIO.output(22, GPIO.LOW)   
           
    if read_temp_1()<= set_temp:
       GPIO.output(24, GPIO.LOW)
       
    else:
        GPIO.output(24, GPIO.HIGH)
        time.sleep(300)


User avatar
OutoftheBOTS
Posts: 660
Joined: Tue Aug 01, 2017 10:06 am

Re: Need a little help/input on controller.

Thu Sep 13, 2018 10:48 am

If I understand what you want then something like this might work

Code: Select all

#!/usr/bin/env python3

import os
import glob
import time
from time import sleep
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
#GPIO Pins: 22 fan_mains, 24 compressor_mains
pinList = [22,24]
for i in pinList:
    GPIO.setup(i, GPIO.OUT)
    GPIO.output(i, GPIO.HIGH)

os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

base_dir='/sys/bus/w1/devices/'
device_folder_1=glob.glob(base_dir + '28-041720f964ff')[0]
device_folder_2=glob.glob(base_dir + '28-041720f612ff')[0]
device_folder_3=glob.glob(base_dir + '28-0417211dadff')[0]
device_file_1=device_folder_1 + '/w1_slave'
device_file_2=device_folder_2 + '/w1_slave'
device_file_3=device_folder_3 + '/w1_slave'
set_temp = 50.0
ice_temp = 32.0

def read_temp_raw_1():
    f = open(device_file_1, 'r')
    lines = f.readlines()
    f.close()
    return lines

def read_temp_1():
    lines = read_temp_raw_1()
    while lines[0].strip() [-3:] != 'YES':
        time.sleep(10.0)
        lines = read_temp_raw_1()
    equals_pos = lines[1].find('t=')
    if equals_pos != -1:
        temp_string = lines[1][equals_pos+2:]
        temp_f_1= float(temp_string) / 1000 *9.0 / 5.0 + 32.0
        return temp_f_1

def read_temp_raw_2():
    f = open(device_file_2, 'r')
    lines = f.readlines()
    f.close()
    return lines

def read_temp_2():
    lines = read_temp_raw_2()
    while lines[0].strip() [-3:] != 'YES':
        time.sleep(10.0)
        lines = read_temp_raw_2()
    equals_pos = lines[1].find('t=')
    if equals_pos != -1:
        temp_string = lines[1][equals_pos+2:]
        temp_f_2= float(temp_string) / 1000 *9.0 / 5.0 + 32.0
        return temp_f_2

def read_temp_raw_3():
    f = open(device_file_3, 'r')
    lines = f.readlines()
    f.close()
    return lines

def read_temp_3():
    lines = read_temp_raw_3()
    while lines[0].strip() [-3:] != 'YES':
        time.sleep(10.0)
        lines = read_temp_raw_3()
    equals_pos = lines[1].find('t=')
    if equals_pos != -1:
        temp_string = lines[1][equals_pos+2:]
        temp_f_3= float(temp_string) / 1000 *9.0 / 5.0 + 32.0
        return temp_f_3


wait_till = time.time()		
    
while True:
    print ("Interior Temp:", round(read_temp_1(), 1), "coil:", round(read_temp_2(), 1), "compressor:", round(read_temp_3(),1)
    
	if time.time() > wait_till:
		if read_temp_2()>= ice_temp:
			GPIO.output(22, GPIO.HIGH)
			wait_till = time.time() + 120
       
		else:
			GPIO.output(22, GPIO.LOW)   
           
		if read_temp_1()<= set_temp:
			GPIO.output(24, GPIO.LOW)
       
		else:
			GPIO.output(24, GPIO.HIGH)
			wait_till = time.time() + 300


		
		
		
		

pcmanbob
Posts: 4387
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Need a little help/input on controller.

Thu Sep 13, 2018 11:35 am

So I have made a lot of changes to your code to clean it up.

first I removed the 2 lines

os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

As you no longer need them just enable 1-wire using raspi-config under interfaces.

Then I streamlined you code by using a loop to read the 3 sensors and saved the readings to 3 variables now called "temp_reading"

To prevent your relays cycling quickly you need to add some hysteresis in to the switching of the relays, that is a difference in temperature between switch on and switch off that is controlled by the variable "hysteresis" and is currently set to 1.

So now your fans will switch on at 33 (ice_temp + hysteresis) and off at 32 the 1 deg difference being your hysteresis.

And your compressor will now switch off 49 (set_temp - hysteresis) and on at 51 (set_temp + hysteresis) the 2 deg difference being your hysteresis.

the delay between running the loop is currently set to 10 seconds by the variable "delay" you could increase this to 60 seconds or possible several minutes as the room temp will not change that fast, I suggest you find the ideal delay by experimentation on your actual setup, but don't go to long or you could end up exceeding your set temperatures.

So heres the code

Code: Select all

#!/usr/bin/env python3

from time import sleep
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
#GPIO Pins: 22 fan_mains, 24 compressor_mains
pinList = [22,24]
for i in pinList:
    GPIO.setup(i, GPIO.OUT)
    GPIO.output(i, GPIO.HIGH)

sensorids = ["28-041720f964ff", "28-041720f612ff", "28-0417211dadff"]  # please check sensor ID's are correct and in correct order

temp_reading = [0]*3

set_temp = 50.0
ice_temp = 32.0
hysteresis = 1 # this is the teprature difference between on amd off
delay = 10 # this is the delay between each cycle of the loop

def read_temp_raw():
    f = open(device_file, "r")
    lines = f.readlines()
    f.close()
    return lines
 
def read_temp():
    lines = read_temp_raw()
    while lines[0].strip()[-3:] != "YES":
        time.sleep(0.2)
        lines = read_temp_raw()
    equals_pos = lines[1].find("t=")
    if equals_pos != -1:
        temp_string = lines[1][equals_pos+2:]
        temp_f= float(temp_string) / 1000 *9.0 / 5.0 + 32.0
        return temp_f
    
    
while True:
        for sensor in range(len(sensorids)):
            device_file = "/sys/bus/w1/devices/"+ sensorids[sensor] +"/w1_slave"
            temp_reading[sensor] = (read_temp())
            
        print ("Interior Temp:", round(temp_reading[0], 1), "coil:", round(temp_reading[1], 1), "compressor:", round(temp_reading[2],1))
       
        if temp_reading[1]>= (ice_temp + hysteresis):
            GPIO.output(22, GPIO.HIGH)
        
        elif temp_reading[1]<= ice_temp:
            GPIO.output(22, GPIO.LOW)   
           
        if temp_reading[0]<= (set_temp - hysteresis):
            GPIO.output(24, GPIO.LOW)
       
        elif temp_reading[0]>=(set_temp + hysteresis):
            GPIO.output(24, GPIO.HIGH)
            
        sleep(delay)
code runs without error but can't test actual operation without actual fridge.

I was not sure of the operation of your relays whether they were active high or active low so I left the operation as you had it and just added the hysteresis to your existing setup, if you find it the wrong way round you will need to make some changes.

one final thing I hope you are not running the compressor using this code only as you need a high and low pressure safety switch in the circuit as well to prevent damage to your system in the event of high or low pressure.

please ask if you need any explanation of how the code works or help with changing the hysteresis if the relay operation is incorrect.
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

JoshD086
Posts: 4
Joined: Tue Sep 11, 2018 2:47 am

Re: Need a little help/input on controller.

Thu Sep 13, 2018 2:39 pm

Thank you for your replies. In all honesty, i knew i needed hysteresis like a normal temp controller. But I had no idea how to implement it or what it was called , still learning everyday. I saved each code and ran them on the test bench this morning and so far i can tell a difference in operation. I am going to run pcmanbob's version of code on the actual system to give it the real test and then post back here. I greatly appreciate you guys for the help given, and not being too hard on me.

User avatar
OutoftheBOTS
Posts: 660
Joined: Tue Aug 01, 2017 10:06 am

Re: Need a little help/input on controller.

Thu Sep 13, 2018 7:55 pm

I have not looked at pcmanbob code. I did only look over your code briefly to get an idea of what was going on and did see many places for optimization but I didn't change anything there as I just changed the bit that you asked for
The while loop is where most of the trouble is, I think. I would like to be able to keep the temp readings printing while the script is running
i.e I removed the time.sleep() that was blocking the printing

JoshD086
Posts: 4
Joined: Tue Sep 11, 2018 2:47 am

Re: Need a little help/input on controller.

Mon Sep 17, 2018 12:11 am

So I had a chance to run pcmanbobs code on the system and it’s working well. I think I need to mess with the setpoints a little and fine tune it, but so far so good. And in regards to the pressure switches, yes the compressor has them internal to the unitized compressor. My relays will control the fan and compressor power input, but switches will still control the safety aspect. Thanks again for your help.

Return to “Automation, sensing and robotics”

Who is online

Users browsing this forum: No registered users and 14 guests