def tempControlProc(sensor, proc): #Pipe to communicate with "Get Temperature Process" parent_conn_temp, child_conn_temp = Pipe() ptemp = Process(name = "gettempProc", target=gettempProc, args=(child_conn_temp, sensor)) ptemp.daemon = True ptemp.start() #Pipe to communicate with "Heat Process" parent_conn_heat, child_conn_heat = Pipe() pheat = Process(name = "heatProcGPIO", target=heatProcGPIO, args=(child_conn_heat,sensor)) pheat.daemon = True pheat.start() temp_ma_list = [] temp_ma = 0.0 readyPIDcalc = False while (True): # Temperature Poll readytemp = False while parent_conn_temp.poll(): #Poll Get Temperature Process Pipe temp_C, sensorID, elapsed = parent_conn_temp.recv() #non blocking receive from Get Temperature Process # Write temperature to DB if temp_C != -99: sensor.temp_C = temp_C sensor.elapsed = elapsed conn = sqlite3.connect(config['dbFile']) add_temp_reading(conn,datetime.datetime.utcnow(),sensorID,temp_C) conn.close() print sensor.id + ": " + "{:7.2f}".format(sensor.temp_C) + "C, Setpoint: " + "{:7.2f}".format(sensor.set_point) + "C, elapsed: " + sensor.elapsed + ", duty: " + "{:6.0f}".format(sensor.duty_cycle)+"%" if temp_C == -99: #print sensorID + ": --" + "C, elapsed: " + elapsed continue if (config['tempUnits'] == 'F'): temp = (9.0/5.0)*temp_C + 32 else: temp = temp_C temp_str = "%3.2f" % temp readytemp = True if readytemp == True: if sensor.heaterEnabled == 1: temp_ma_list.append(temp) #smooth data temp_ma = 0.0 #moving avg init while (len(temp_ma_list) > sensor.smoothPts): temp_ma_list.pop(0) #remove oldest elements in list if (len(temp_ma_list) < sensor.smoothPts): for temp_pnt in temp_ma_list: temp_ma += temp_pnt temp_ma /= len(temp_ma_list) else: #len(temp_ma_list) == num_pnts_smooth for temp_idx in range(sensor.smoothPts): temp_ma += temp_ma_list[temp_idx] temp_ma /= sensor.smoothPts #print "len(temp_ma_list) = %d" % len(temp_ma_list) #print "Num Points smooth = %d" % num_pnts_smooth #print "temp_ma = %.2f" % temp_ma #print temp_ma_list #calculate PID every cycle if (readyPIDcalc == True): sensor.duty_cycle = pid.calcPID_reg4(temp_ma, sensor.set_point, True) #send to heat process every cycle parent_conn_heat.send([sensor.cycle_time, sensor.duty_cycle]) readyPIDcalc = False while parent_conn_heat.poll(): #Poll Heat Process Pipe sensor.cycle_time, sensor.duty_cycle = parent_conn_heat.recv() #non blocking receive from Heat Process ") conn = sqlite3.connect(config['dbFile']) add_duty_reading(conn,datetime.datetime.utcnow(),sensor.id,sensor.duty_cycle,sensor.set_point) conn.close() pid = PIDController.pidpy(sensor.cycle_time, sensor.Kc, sensor.Ti, sensor.Td) #init pid readyPIDcalc = True
def tempControlProc(myTempSensor, display, pinNum, readOnly, paramStatus, statusQ, conn): mode, cycle_time, duty_cycle, boil_duty_cycle, set_point, boil_manage_temp, num_pnts_smooth, \ k_param, i_param, d_param = unPackParamInitAndPost(paramStatus) p = current_process() print('Starting:', p.name, p.pid) #Pipe to communicate with "Get Temperature Process" parent_conn_temp, child_conn_temp = Pipe() #Start Get Temperature Process ptemp = Process(name="gettempProc", target=gettempProc, args=(child_conn_temp, myTempSensor)) ptemp.daemon = True ptemp.start() #Pipe to communicate with "Heat Process" parent_conn_heat, child_conn_heat = Pipe() #Start Heat Process pheat = Process(name="heatProcGPIO", target=heatProcGPIO, args=(cycle_time, duty_cycle, pinNum, child_conn_heat)) pheat.daemon = True pheat.start() temp_ma_list = [] manage_boil_trigger = False tempUnits = xml_root.find('Temp_Units').text.strip() numTempSensors = 0 for tempSensorId in xml_root.iter('Temp_Sensor_Id'): numTempSensors += 1 temp_ma = 0.0 #overwrite log file for new data log ff = open("brewery" + str(myTempSensor.sensorNum) + ".csv", "wb") ff.close() readyPIDcalc = False while (True): readytemp = False while parent_conn_temp.poll(): #Poll Get Temperature Process Pipe temp_C, tempSensorNum, elapsed = parent_conn_temp.recv( ) #non blocking receive from Get Temperature Process if temp_C == -99: print("Bad Temp Reading - retry") continue if (tempUnits == 'F'): temp = (9.0 / 5.0) * temp_C + 32 else: temp = temp_C temp_str = "%3.2f" % temp display.showTemperature(temp_str) readytemp = True if readytemp == True: if mode == "auto": temp_ma_list.append(temp) #smooth data temp_ma = 0.0 #moving avg init while (len(temp_ma_list) > num_pnts_smooth): temp_ma_list.pop(0) #remove oldest elements in list if (len(temp_ma_list) < num_pnts_smooth): for temp_pnt in temp_ma_list: temp_ma += temp_pnt temp_ma /= len(temp_ma_list) else: #len(temp_ma_list) == num_pnts_smooth for temp_idx in range(num_pnts_smooth): temp_ma += temp_ma_list[temp_idx] temp_ma /= num_pnts_smooth #print "len(temp_ma_list) = %d" % len(temp_ma_list) #print "Num Points smooth = %d" % num_pnts_smooth #print "temp_ma = %.2f" % temp_ma #print temp_ma_list #calculate PID every cycle if (readyPIDcalc == True): duty_cycle = pid.calcPID_reg4(temp_ma, set_point, True) #send to heat process every cycle parent_conn_heat.send([cycle_time, duty_cycle]) readyPIDcalc = False if mode == "boil": if (temp > boil_manage_temp) and (manage_boil_trigger == True): #do once manage_boil_trigger = False duty_cycle = boil_duty_cycle parent_conn_heat.send([cycle_time, duty_cycle]) #put current status in queue try: paramStatus = packParamGet(numTempSensors, myTempSensor.sensorNum, temp_str, tempUnits, elapsed, mode, cycle_time, duty_cycle, \ boil_duty_cycle, set_point, boil_manage_temp, num_pnts_smooth, k_param, i_param, d_param) statusQ.put(paramStatus) #GET request except Full: pass while (statusQ.qsize() >= 2): statusQ.get() #remove old status print("Current Temp: %3.2f deg %s, Heat Output: %3.1f%%" \ % (temp, tempUnits, duty_cycle)) logdata(myTempSensor.sensorNum, temp, duty_cycle) readytemp == False #if only reading temperature (no temp control) if readOnly: continue while parent_conn_heat.poll(): #Poll Heat Process Pipe cycle_time, duty_cycle = parent_conn_heat.recv( ) #non blocking receive from Heat Process display.showDutyCycle(duty_cycle) readyPIDcalc = True readyPOST = False while conn.poll( ): #POST settings - Received POST from web browser or Android device paramStatus = conn.recv() mode, cycle_time, duty_cycle_temp, boil_duty_cycle, set_point, boil_manage_temp, num_pnts_smooth, \ k_param, i_param, d_param = unPackParamInitAndPost(paramStatus) readyPOST = True if readyPOST == True: if mode == "auto": display.showAutoMode(set_point) print("auto selected") pid = PIDController.pidpy(cycle_time, k_param, i_param, d_param) #init pid duty_cycle = pid.calcPID_reg4(temp_ma, set_point, True) parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "boil": display.showBoilMode() print("boil selected") boil_duty_cycle = duty_cycle_temp duty_cycle = 100 #full power to boil manage temperature manage_boil_trigger = True parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "manual": display.showManualMode() print("manual selected") duty_cycle = duty_cycle_temp parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "off": display.showOffMode() print("off selected") duty_cycle = 0 parent_conn_heat.send([cycle_time, duty_cycle]) readyPOST = False time.sleep(.01)
def tempControlProc(configFile, num, mode, cycle_time, duty_cycle, boil_duty_cycle, set_point, boil_manage_temp, num_pnts_smooth, k_param, i_param, d_param, statusQ, conn): initGlobalConfig(configFile) if useLCD: # initialize LCD ser = serial.Serial("/dev/ttyAMA0", 9600) ser.write("?BFF") time.sleep(.1) # wait 100msec ser.write("?f?a") ser.write("?y0?x00PID off ") ser.write("?y1?x00HLT:") ser.write("?y3?x00Heat: off ") ser.write("?D70609090600000000") # define degree symbol time.sleep(.1) # wait 100msec p = current_process() print 'Starting Controller ', num, ':', p.name, p.pid # Pipe to communicate with "Get Temperature Process" parent_conn_temp, child_conn_temp = Pipe() # Start Get Temperature Process ptemp = Process(name="gettempProc", target=gettempProc, args=( configFile, num, child_conn_temp, )) ptemp.daemon = True ptemp.start() # Pipe to communicate with "Heat Process" parent_conn_heat, child_conn_heat = Pipe() # Start Heat Process pheat = Process(name="heatProcGeneric", target=heatProcGeneric, args=(configFile, num, cycle_time, duty_cycle, child_conn_heat)) pheat.daemon = True pheat.start() temp_F_ma_list = [] manage_boil_trigger = False elapsed = 0.0 while (True): readytemp = False if ptemp.is_alive() == False: # switch off if temperature process fails to deliver data parent_conn_heat.send([cycle_time, 0]) print "Emergency Stop, no temperature" time.sleep(2) sys.exit() if pheat.is_alive() == False: print "Emergency Stop, no heater" sys.exit() while parent_conn_temp.poll(): # Poll Get Temperature Process Pipe temp_C, elapsedMeasurement = parent_conn_temp.recv( ) # non blocking receive from Get Temperature Process elapsed = elapsed + float(elapsedMeasurement) if temp_C == -99: print "Bad Temp Reading - retry" continue temp_F = (9.0 / 5.0) * temp_C + 32 temp_F_ma_list.append(temp_F) # smooth data temp_F_ma = 0.0 # moving avg init while (len(temp_F_ma_list) > num_pnts_smooth): temp_F_ma_list.pop(0) # remove oldest elements in list if (len(temp_F_ma_list) < num_pnts_smooth): for temp_pnt in temp_F_ma_list: temp_F_ma += temp_pnt temp_F_ma /= len(temp_F_ma_list) else: # len(temp_F_ma_list) == num_pnts_smooth for temp_idx in range(num_pnts_smooth): temp_F_ma += temp_F_ma_list[temp_idx] temp_F_ma /= num_pnts_smooth # print "len(temp_F_ma_list) = %d" % len(temp_F_ma_list) # print "Num Points smooth = %d" % num_pnts_smooth # print "temp_F_ma = %.2f" % temp_F_ma # print temp_F_ma_list temp_C_str = "%3.2f" % temp_C temp_F_str = "%3.2f" % temp_F # write to LCD if useLCD: ser.write("?y1?x05") ser.write(temp_F_str) ser.write("?7") # degree time.sleep(.005) # wait 5msec ser.write("F ") readytemp = True if readytemp == True: if mode == "auto": # calculate PID every cycle - always get latest temperature # print "Temp F MA %.2f" % temp_F_ma duty_cycle = pid.calcPID_reg4(temp_F_ma, set_point, True) # send to heat process every cycle parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "boil": if (temp_F > boil_manage_temp) and (manage_boil_trigger == True): # do once manage_boil_trigger = False duty_cycle = boil_duty_cycle parent_conn_heat.send([cycle_time, duty_cycle]) # put current status in queue try: statusQ.put([temp_F_str, elapsed, mode, cycle_time, duty_cycle, set_point, \ boil_manage_temp, num_pnts_smooth, k_param, i_param, d_param]) # GET request except Queue.Full: pass while (statusQ.qsize() >= 2): statusQ.get() # remove old status # print "Temp: %3.2f deg F, Heat Output: %3.1f%% %s %f" % (temp_F, duty_cycle, mode, boil_manage_temp) readytemp == False while parent_conn_heat.poll(): # Poll Heat Process Pipe cycle_time, duty_cycle = parent_conn_heat.recv( ) # non blocking receive from Heat Process # write to LCD if useLCD: ser.write("?y2?x00Duty: ") ser.write("%3.1f" % duty_cycle) ser.write("% ") readyPOST = False while conn.poll( ): # POST settings - Received POST from web browser or Android device mode, cycle_time, duty_cycle_temp, set_point, boil_manage_temp, num_pnts_smooth, k_param, i_param, d_param = conn.recv( ) readyPOST = True if readyPOST == True: if mode == "auto": if useLCD: ser.write("?y0?x00Auto Mode ") ser.write("?y1?x00HLT:") ser.write("?y3?x00Set To: ") ser.write("%3.1f" % set_point) ser.write("?7") # degree time.sleep(.005) # wait 5msec ser.write("F ") print "auto selected" pid = PIDController.pidpy(cycle_time, k_param, i_param, d_param) # init pid duty_cycle = pid.calcPID_reg4(temp_F_ma, set_point, True) if mode == "boil": if useLCD: ser.write("?y0?x00Boil Mode ") ser.write("?y1?x00BK: ") ser.write("?y3?x00Heat: on ") print "boil selected" boil_duty_cycle = duty_cycle_temp duty_cycle = 100 # full power to boil manage temperature manage_boil_trigger = True if mode == "manual": if useLCD: ser.write("?y0?x00Manual Mode ") ser.write("?y1?x00BK: ") ser.write("?y3?x00Heat: on ") print "manual selected" duty_cycle = duty_cycle_temp if mode == "off": if useLCD: ser.write("?y0?x00PID off ") ser.write("?y1?x00HLT:") ser.write("?y3?x00Heat: off ") print "off selected" duty_cycle = 0 parent_conn_heat.send([cycle_time, duty_cycle]) readyPOST = False time.sleep(.01)
def tempControlProc(mode, cycle_time, duty_cycle, set_point, k_param, i_param, d_param, statusQ, conn): #initialize LCD ser = serial.Serial("/dev/ttyAMA0", 9600) ser.write("?BFF") time.sleep(.1) #wait 100msec ser.write("?f?a") ser.write("?y0?x00PID off ") ser.write("?y1?x00HLT:") ser.write("?y3?x00Heat: off ") ser.write("?D70609090600000000") #define degree symbol time.sleep(.1) #wait 100msec p = current_process() print 'Starting:', p.name, p.pid parent_conn_temp, child_conn_temp = Pipe() ptemp = Process(name = "gettempProc", target=gettempProc, args=(child_conn_temp,)) ptemp.daemon = True ptemp.start() parent_conn_heat, child_conn_heat = Pipe() pheat = Process(name = "heatProcGPIO", target=heatProcGPIO, args=(cycle_time, duty_cycle, child_conn_heat)) pheat.daemon = True pheat.start() temp_F_ma_list = [] temp_F_ma = 0.0 while (True): readytemp = False while parent_conn_temp.poll(): temp_C, elapsed = parent_conn_temp.recv() #non blocking receive temp_F = (9.0/5.0)*temp_C + 32 temp_F_ma_list.append(temp_F) #smooth temp data if (len(temp_F_ma_list) == 1): temp_F_ma = temp_F_ma_list[0] elif (len(temp_F_ma_list) == 2): temp_F_ma = (temp_F_ma_list[0] + temp_F_ma_list[1]) / 2.0 elif (len(temp_F_ma_list) == 3): temp_F_ma = (temp_F_ma_list[0] + temp_F_ma_list[1] + temp_F_ma_list[2]) / 3.0 elif (len(temp_F_ma_list) == 4): temp_F_ma = (temp_F_ma_list[0] + temp_F_ma_list[1] + temp_F_ma_list[2] + temp_F_ma_list[3]) / 4.0 else: temp_F_ma = (temp_F_ma_list[0] + temp_F_ma_list[1] + temp_F_ma_list[2] + temp_F_ma_list[3] + \ temp_F_ma_list[4]) / 5.0 temp_F_ma_list.pop(0) #remove oldest element in list temp_C_str = "%3.2f" % temp_C temp_F_str = "%3.2f" % temp_F ser.write("?y1?x05") ser.write(temp_F_str) ser.write("?7") #degree time.sleep(.005) #wait 5msec ser.write("F ") readytemp = True if readytemp == True: if mode == "auto": #calculate PID every cycle - alwyas get latest temp print "Temp F MA %.2f" % temp_F_ma duty_cycle = pid.calcPID_reg4(temp_F_ma, set_point, True) #send to heat process every cycle parent_conn_heat.send([cycle_time, duty_cycle]) if (not statusQ.full()): statusQ.put([temp_F_str, elapsed, mode, cycle_time, duty_cycle, set_point, k_param, i_param, d_param]) #GET request readytemp == False while parent_conn_heat.poll(): #non blocking receive cycle_time, duty_cycle = parent_conn_heat.recv() ser.write("?y2?x00Duty: ") ser.write("%3.1f" % duty_cycle) ser.write("% ") readyPOST = False while conn.poll(): #POST settings mode, cycle_time, duty_cycle_temp, set_point, k_param, i_param, d_param = conn.recv() readyPOST = True if readyPOST == True: if mode == "auto": ser.write("?y0?x00Auto Mode ") ser.write("?y1?x00HLT:") ser.write("?y3?x00Set To: ") ser.write("%3.1f" % set_point) ser.write("?7") #degree time.sleep(.005) #wait 5msec ser.write("F ") print "auto selected" pid = PIDController.pidpy(cycle_time, k_param, i_param, d_param) #init pid duty_cycle = pid.calcPID_reg4(temp_F_ma, set_point, True) parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "manual": ser.write("?y0?x00Manual Mode ") ser.write("?y1?x00BK: ") ser.write("?y3?x00Heat: on ") print "manual selected" duty_cycle = duty_cycle_temp parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "off": ser.write("?y0?x00PID off ") ser.write("?y1?x00HLT:") ser.write("?y3?x00Heat: off ") print "off selected" duty_cycle = 0 parent_conn_heat.send([cycle_time, duty_cycle]) readyPOST = False time.sleep(.01)
def tempControlProc (myTempSensor, display, pinNum, readOnly, paramStatus, statusQ, subscribeQ, conn): mode, cycle_time, duty_cycle, dry_duty_cycle, set_point, dry_manage_temp, num_pnts_smooth, \ k_param, i_param, d_param ,option = param.unPackParamInitAndPost(paramStatus) p = current_process() print ("Starting , {}, pid {}, param {}".format( p.name, p.pid,paramStatus)) #Pipe to communicate with "Get Temperature Process" parent_conn_temp, child_conn_temp = Pipe() #Start Get Temperature Process ptemp = Process(target=gettempProc, args=( myTempSensor,child_conn_temp)) ptemp.daemon = True ptemp.start() lck.acquire() print ("Starting , {}, pid {}".format( ptemp.name, ptemp.pid)) lck.release() #Pipe to communicate with "Heat Process" parent_conn_heat, child_conn_heat = Pipe() #Start Heat Process pheat = Process( name ="heatProcGPIO",target=heatProcGPIO, args=(cycle_time, duty_cycle, pinNum, child_conn_heat)) pheat.daemon = True pheat.start() lck.acquire() print " starting {} , pid {}, pin {},readOnly {}".format( pheat.name, pheat.pid, pinNum,readOnly) lck.release() #time interval to write to iot iottime=time.time() temp_ma_list = [] #MVA temp list manage_dry_trigger = True#False tempUnits = xml_root.find('Temp_Units').text.strip() temp_ma = 0.0 #MVA temp humidity=0 #overwrite log file for new data log # ff = open("dryer" + str(myTempSensor.sensorNum) + ".csv", "wb") # ff.close() mode1 = None lastwrite=time.time() while (True): readytemp = False while parent_conn_temp.poll(): #Poll Get Temperature Process Pipe. Return whether there is any data available to be read. temp_C, humidity,tempSensorNum, elapsed = parent_conn_temp.recv() #non blocking receive from Get Temperature Process. Return an object sent from the other end of the connection using if temp_C == -99: print "Bad Temp Reading - retry" continue if (tempUnits == 'F'): temp = (9.0/5.0)*temp_C + 32 else: temp = temp_C temp_str = "%3.2f" % temp #12.3456789 > 12.35 display.showTemperature(temp_str) readytemp = True if readytemp == True: lck.acquire() print "tempControlProc :readytemp {}, set_point {}, duty_cycle {}, pin {}, temp {}, mode {},numTempSensors {} ".format(readytemp, set_point ,duty_cycle, pinNum, temp, mode,numTempSensors ) lck.release() while (parent_conn_heat.poll()): #get last poll(1) 1sek blok cycle_time, duty_cycle = parent_conn_heat.recv() #get status from mqtt subsrciber if cert is not None: lck.acquire() print"tempControlProc getting message from IOT subscription" lck.release() try: while not queueSub.empty() or queueSub.get(block=False)== 'DONE': msg = queueSub.get(block=False) # Read from the queue and do nothing print"tempControlProc queueSub ", msg if (msg == 'DONE'): #print "tempControlProc DONE, pin {}".format(pinNum) break elif msg == "False": readOnly=True if mode1 is None: mode1=mode mode="stopped" duty_cycle=0 parent_conn_heat.send ([cycle_time, duty_cycle]) #print "tempControlProct queueSub readonly {}, mode {},mode1 {}, pin{}".format(readOnly, mode,mode1, pinNum) elif msg == "stopped": readOnly=True mode="stopped" #print "tempControlProct queueSub readonly {}, mode {}, mode1 {},pin{}".format(readOnly, mode, mode1,pinNum) elif msg == "True": if mode1 is not None: mode=mode1 mode1 = None readOnly=False #print "tempControlProct queueSub readonly {}, mode {}, mode1 {}, pin{}".format(readOnly, mode, mode1,pinNum) break except Empty: pass if mode == "off": lck.acquire() print ("stoped", (time.time()-stop)) lck.release() import offGPIO GPIO.cleanup() # this ensures a clean exit os.killpg(0, signal.SIGKILL) # kill all processes in my group if mode =="auto": temp_ma_list.append(temp) #smooth data temp_ma = 0.0 #moving temp avg init while (len(temp_ma_list) > num_pnts_smooth): temp_ma_list.pop(0) #remove oldest elements in list if (len(temp_ma_list) < num_pnts_smooth): for temp_pnt in temp_ma_list: temp_ma += temp_pnt temp_ma /= len(temp_ma_list) else: #len(temp_ma_list) == num_pnts_smooth for temp_idx in range(num_pnts_smooth): temp_ma += temp_ma_list[temp_idx] temp_ma /= num_pnts_smooth #print "len(temp_ma_list) = %d" % len(temp_ma_list) #print "Num Points smooth = %d" % num_pnts_smooth #print "temp_ma = %.2f" % temp_ma #print temp_ma_list #calculate PID every cycle if (readyPIDcalc == True): #https://www.raspberrypi.org/forums/viewtopic.php?f=35&t=62438&p=463458 #https://www.raspberrypi.org/forums/viewtopic.php?t=63714&p=471636 set_point=dry_manage_temp pid = PIDController.pidpy(cycle_time, k_param, i_param, d_param) #init pid duty_cycle = pid.calcPID_reg4(temp_ma, set_point, True) #ogrevalna stopnja cikla #send to heat process every cycle parent_conn_heat.send([cycle_time, duty_cycle]) # readyPIDcalc = False lck.acquire() print "tempControlProc : duty_cycle {}, k {}, i {}, d {},temp_ma {} ".format(duty_cycle, k_param, i_param, d_param, temp_ma ) lck.release() if mode =="heating" : if (temp >= dry_manage_temp):# and (manage_dry_trigger == True): #send 0% heat power manage_dry_trigger = False duty_cycle = 0 parent_conn_heat.send ([cycle_time, duty_cycle]) elif (temp < set_point-4): #dry_manage_temp-4):# and (manage_dry_trigger == True): #send 100% heat power manage_dry_trigger = False duty_cycle = 100 parent_conn_heat.send ([cycle_time, duty_cycle])#2.0,100 elif (temp <= set_point-2): #dry_manage_temp-2):# and (manage_dry_trigger == True): #60% heat power to lower heater manage_dry_trigger = False if pinNum == 22: duty_cycle = 100 else: duty_cycle = 0 parent_conn_heat.send([cycle_time, duty_cycle])#2.0,600 elif (temp < set_point):#dry_manage_temp):# and (manage_dry_trigger == True): #send 0% heat power and 50% heat power to lower heater manage_dry_trigger = False if pinNum == 22: duty_cycle = 50 else: duty_cycle = 0 parent_conn_heat.send([cycle_time, duty_cycle])#2.0,600 elif (temp >= set_point):#dry_manage_temp):# and (manage_dry_trigger == True): #send 0% heat power to heater manage_dry_trigger = False duty_cycle = 0 parent_conn_heat.send([cycle_time, duty_cycle])#2.0,600 #put current status in queue try: paramStatus = packParamGet(numTempSensors, myTempSensor.sensorNum, temp_str, tempUnits, elapsed, mode, cycle_time, duty_cycle, \ dry_duty_cycle, set_point, dry_manage_temp, num_pnts_smooth, k_param, i_param, d_param,option ) statusQ.put(paramStatus) #GET request except Full: pass while (statusQ.qsize() >= 2): statusQ.get() #remove old status # print "Current Temp: %3.2f deg %s, Heat Output: %3.1f%%" \ # % (temp, tempUnits, duty_cycle) logdata(myTempSensor.sensorNum, temp, duty_cycle)#senzorPin namesto Num readytemp == False #if mode is stopped and only reading temperature (no temp control) if mode == 'stopped' and readOnly: duty_cycle = 0 parent_conn_heat.send([cycle_time, duty_cycle]) if DEBUG: lck.acquire() print "loop continue, mode {}, Pin {}".format(mode, pinNum) lck.release() #if only reading temperature (no temp control) if readOnly: if DEBUG: lck.acquire() print "loop continue, readonly {}, Pin {}".format(readOnly, pinNum) lck.release() continue if getruntime() >= (dry_time*60): lck.acquire() print "exit dtime {}> dry_time {} ".format(getruntime(), dry_time*60) lck.release() GPIO.cleanup() # this ensures a clean exit os.killpg(0, signal.SIGKILL) # kill all processes in my group if time.time()-iottime > sleep and cert is not None: iottime=time.time() weight=10 humidity=10 mode0="'"+str(mode)+"'" mode0=str(mode0) iot= iot_mqtt_publisher2( thing,cert) lck.acquire() print ("Send to IOT from temp_control",thing,cert,round(temp),round(temp),mode0,set_point,round(humidity),round(weight),round(getruntime())) lck.release() iot.send(round(temp,2),round(temp,2),mode0,set_point,round(humidity,2),round(weight,2),round(getruntime(),0)) # parent_connIOT.send([round(temp,2),round(temp,2),mode0,set_point,round(humidity,2),round(weight,2),round(getruntime(),0)]) print "Write pin {}, time {}, sleep {}".format(pinNum , time.time()- lastwrite , sleep) if pinNum == 22 and time.time()- lastwrite > sleep: #and temp > 0 tab=" " line="{d}{t}{l}{t}{m}{t}{n}{t}{o}\r\n".format(d=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),l=(format(temp,'.2f')),m=(format(temp-1,'.2f')),n=format(humidity,'.2f'),o=0,t=tab) lck.acquire() print("write {} to {}.csv".format( line,filename)) lck.release() with open( filename+".csv", "a") as myfile: myfile.write(line) myfile.close() lastwrite=time.time() # print "next loop" # while parent_conn_heat.poll(): #Poll Heat Process Pipe # cycle_time, duty_cycle = parent_conn_heat.recv() #non blocking receive from Heat Process # display.showDutyCycle(duty_cycle) # print "tempControlProc parent_conn_heat",parent_conn_heat.poll(), cycle_time, duty_cycle # readyPIDcalc = True readyPOST = False while conn.poll(): #POST settings - Received POST from web browser or Android device paramStatus = conn.recv() mode, cycle_time, duty_cycle, dry_duty_cycle, set_point, dry_manage_temp, num_pnts_smooth, \ k_param, i_param, d_param ,option = param.unPackParamInitAndPost(paramStatus) readyPOST = True if readyPOST == True: #print "tempControlProc POST conn_poll duty_cycle {}, pin {} ,mode {}, cycle_time {} ".format( duty_cycle, pinNum, mode, cycle_time) if mode == "auto": display.showAutoMode(set_point) lck.acquire() print "auto selected" lck.release() for pin in pinFanList: if not GPIO.input(pin): # returns 1 print "Fan started", pin GPIO.output(pin, ON) pid = PIDController.pidpy(cycle_time, k_param, i_param, d_param) #init pid duty_cycle = pid.calcPID_reg4(temp_ma, set_point, True) parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "heating": display.showDryMode() lck.acquire() print "heating selected" lck.release() for pin in pinFanList: if not GPIO.input(pin): # returns 1 print "Fan started", pin GPIO.output(pin, ON) # dry_duty_cycle = duty_cycle_temp duty_cycle = dry_duty_cycle #100 #full power to dry manage temperature manage_dry_trigger = True parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "manual": display.showManualMode() lck.acquire() print "manual selected" lck.release() for pin in pinFanList: if GPIO.input(pin): # returns 1 print "Fan started", pin GPIO.output(pin, HIGH) duty_cycle = dry_duty_cycle parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "off": display.showOffMode() lck.acquire() print "off selected" lck.release() duty_cycle = 0 readonly=True parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "stopped": display.showOffMode() lck.acquire() print "stop selected" lck.release() GPIO.output(piNum, GPIO.LOW) for pin in pinFanList: print "Fan stopped", pin GPIO.output(pin, LOW) duty_cycle = 0 parent_conn_heat.send([cycle_time, duty_cycle]) readyPOST = False time.sleep(.01)
def tempControlProc(mode, cycle_time, duty_cycle, set_point, k_param, i_param, d_param, steam_temp, steam_cycle, statusQ, conn): p = current_process() logger = logging.getLogger('ispresso').getChild("tempControlProc") logger.info('Starting:' + p.name + ":" + str(p.pid)) try: parent_conn_temp, child_conn_temp = Pipe() ptemp = Process(name="gettempProc", target=gettempProc, args=(child_conn_temp,)) ptemp.daemon = True ptemp.start() parent_conn_heat, child_conn_heat = Pipe() pheat = Process(name="heatProc", target=heatProc, args=(cycle_time, duty_cycle, child_conn_heat)) pheat.daemon = True pheat.start() pid = PIDController.pidpy(cycle_time, k_param, i_param, d_param) # init pid pidSteam = PIDController.pidpy(steam_cycle, k_param, i_param, d_param) flush_cache = False last_temp_C = 0 while (True): time.sleep(0.1) readytemp = False while parent_conn_temp.poll(): temp_C, elapsed = parent_conn_temp.recv() # non blocking receive mode = scheduled_mode(mode) # check to see if scheduler should fire on or off -- MOVING THIS as the OFF doesnt seem to fire.. if temp_C > 0: # the 1-wire sensor sometimes comes back with 0 -- need to fix that by holding on to last value. last_temp_C = temp_C else: temp_C = last_temp_C temp_F = (9.0 / 5.0) * temp_C + 32 temp_C_str = "%3.0f" % temp_C #temp_SV_C = (set_point - 32) / 1.8 temp_SV_str = "%3.0f" % set_point temp_F_str = "%3.2f" % temp_F temp_F_pretty = "%3.0f" % temp_F if mode == "steam": status = "Steaming " elif mode == "auto": status = "Heating " else: status = "Standby" if mem.flag_pump_on: mem.lcd_connection.send([ 'pV:' +str(temp_C_str) + ' ' +'sV:' +str(temp_SV_str) , None , 0]) else: mem.lcd_connection.send([ 'pV:' +str(temp_C_str) + ' ' +'sV:' +str(temp_SV_str) , '' +str(status) , 0]) readytemp = True if readytemp == True: if mode == "steam": duty_cycle = pidSteam.calcPID_reg4(temp_C, steam_temp, True) #duty_cycle = 100 parent_conn_heat.send([steam_cycle, duty_cycle]) GPIO.output(gpio_btn_steam_led, GPIO.HIGH) GPIO.output(gpio_btn_heat_led, GPIO.LOW) elif mode == "auto": duty_cycle = pid.calcPID_reg4(temp_C, set_point, True) parent_conn_heat.send([cycle_time, duty_cycle]) GPIO.output(gpio_btn_heat_led, GPIO.HIGH) GPIO.output(gpio_btn_steam_led, GPIO.LOW) elif mode == "off": duty_cycle = 0 parent_conn_heat.send([cycle_time, duty_cycle]) GPIO.output(gpio_btn_heat_led, GPIO.LOW) GPIO.output(gpio_btn_steam_led, GPIO.LOW) if (not statusQ.full()): statusQ.put([temp_C, elapsed, mode, cycle_time, duty_cycle, set_point, k_param, i_param, d_param, steam_temp, steam_cycle]) # GET request readytemp == False while parent_conn_heat.poll(): # non blocking receive cycle_time, duty_cycle = parent_conn_heat.recv() while conn.poll(): # POST settings mode, cycle_time, duty_cycle_temp, set_point, k_param, i_param, d_param, steam_temp, steam_cycle , flush_cache = conn.recv() if flush_cache: mem.cache_day = None # this should force cache flush flush_cache = False mode = scheduled_mode(mode) # check to see if scheduler should fire on or off except: exc_type, exc_value, exc_traceback = sys.exc_info() logger.error(''.join('!! ' + line for line in traceback.format_exception(exc_type, exc_value, exc_traceback)))
#!/usr/bin/python from pid import pidpy as PIDController set_point=40 cycle_time=2.2 k_param=10 k_param=10 i_param=1.8 i_param=33 d_param=5 temp_ma=12 pid = PIDController.pidpy(cycle_time, k_param, i_param, d_param) #init pid for i in range (10,33): duty_cycle = pid.calcPID_reg4(i+temp_ma, set_point, True) #ogrevalna stopnja cikla print "cycle_time, k_param, i_param, d_param,duty_cycle,temp_ma, set_point", cycle_time, k_param, i_param, d_param,duty_cycle,temp_ma+i, set_point
def tempControlChild(thisparam, statusQ, conn): p = current_process() print 'Starting:', p.name, p.pid parent_conn_temp, child_conn_temp = Pipe() ptemp = Process(name = "gettempProc", target=gettempProc, args=(thisparam, child_conn_temp,)) ptemp.daemon = True ptemp.start() parent_conn_heat, child_conn_heat = Pipe() pheat = Process(name = "heatProc", target=heatProc, args=(thisparam.gpio, thisparam.cycle_time, thisparam.duty_cycle, child_conn_heat)) pheat.daemon = True pheat.start() temp_F_ma_list = [] temp_F_ma = 0.0 temp_C = -100 while (True): readytemp = False while parent_conn_temp.poll(): temp_C_temp, elapsed = parent_conn_temp.recv() #non blocking receive if temp_C_temp != -100: temp_C = temp_C_temp try: temp_F = (9.0/5.0)*temp_C + 32 except: temp_F = 0.0 if thisparam.name == "kettle" : kettle_param.temp = temp_F if thisparam.name == "mlt" : mlt_param.temp = temp_F if thisparam.name == "hlt" : hlt_param.temp = temp_F thisparam.temp = temp_F temp_F_ma_list.append(temp_F) #print temp_F_ma_list #smooth temp data # if (len(temp_F_ma_list) == 1): temp_F_ma = temp_F_ma_list[0] elif (len(temp_F_ma_list) == 2): temp_F_ma = (temp_F_ma_list[0] + temp_F_ma_list[1]) / 2.0 elif (len(temp_F_ma_list) == 3): temp_F_ma = (temp_F_ma_list[0] + temp_F_ma_list[1] + temp_F_ma_list[2]) / 3.0 elif (len(temp_F_ma_list) == 4): temp_F_ma = (temp_F_ma_list[0] + temp_F_ma_list[1] + temp_F_ma_list[2] + temp_F_ma_list[3]) / 4.0 else: temp_F_ma = (temp_F_ma_list[0] + temp_F_ma_list[1] + temp_F_ma_list[2] + temp_F_ma_list[3] + \ temp_F_ma_list[4]) / 5.0 temp_F_ma_list.pop(0) #remove oldest element in list #print "Temp F MA %.2f" % temp_F_ma temp_C_str = "%3.2f" % temp_C temp_F_str = "%3.2f" % temp_F readytemp = True if readytemp == True: if thisparam.mode == "auto": #calculate PID every cycle - alwyas get latest temp #duty_cycle = pid.calcPID(float(temp), set_point, True) #set_point_C = (5.0/9.0)*(set_point - 32) print "Temp F MA %.2f" % temp_F_ma thisparam.duty_cycle = pid.calcPID_reg4(temp_F_ma, thisparam.set_point, True) #send to heat process every cycle parent_conn_heat.send([thisparam.cycle_time, thisparam.duty_cycle]) if (not statusQ.full()): statusQ.put([thisparam.name, thisparam.temp]) #GET request readytemp == False while parent_conn_heat.poll(): #non blocking receive cycle_time, duty_cycle = parent_conn_heat.recv() readyPOST = False while conn.poll(): #POST settings mode, cycle_time, duty_cycle_temp, set_point, k_param, i_param, d_param = conn.recv() readyPOST = True if readyPOST == True: if mode == "auto": #pid = PIDController.PID(cycle_time, k_param, i_param, d_param) #init pid #duty_cycle = pid.calcPID(float(temp), set_point, True) pid = PIDController.pidpy(thisparam.cycle_time, thisparam.k_param, thisparam.i_param, thisparam.d_param) #init pid #set_point_C = (5.0/9.0)*(set_point - 32) thisparam.duty_cycle = pid.calcPID_reg4(temp_F_ma, thisparam.set_point, True) parent_conn_heat.send([thisparam.cycle_time, thisparam.duty_cycle]) if mode == "manual": thisparam.duty_cycle = thisparam.duty_cycle_temp parent_conn_heat.send([thisparam.cycle_time, thisparam.duty_cycle]) if mode == "off": duty_cycle = 0 parent_conn_heat.send([thisparam.cycle_time, thisparam.duty_cycle]) readyPOST = False time.sleep(.01)
def tempControlProc(myTempSensor, display, pinNum, readOnly, paramStatus, statusQ, conn): mode, cycle_time, duty_cycle, boil_duty_cycle, set_point, boil_manage_temp, num_pnts_smooth, \ k_param, i_param, d_param = unPackParamInitAndPost(paramStatus) p = current_process() print 'Starting:', p.name, p.pid #Pipe to communicate with "Get Temperature Process" parent_conn_temp, child_conn_temp = Pipe() #Start Get Temperature Process ptemp = Process(name = "gettempProc", target=gettempProc, args=(child_conn_temp, myTempSensor)) ptemp.daemon = True ptemp.start() #Pipe to communicate with "Heat Process" parent_conn_heat, child_conn_heat = Pipe() #Start Heat Process pheat = Process(name = "heatProcGPIO", target=heatProcGPIO, args=(cycle_time, duty_cycle, pinNum, child_conn_heat)) pheat.daemon = True pheat.start() temp_ma_list = [] manage_boil_trigger = False tempUnits = xml_root.find('Temp_Units').text.strip() numTempSensors = 0 for tempSensorId in xml_root.iter('Temp_Sensor_Id'): numTempSensors += 1 temp_ma = 0.0 #overwrite log file for new data log ff = open("brewery" + str(myTempSensor.sensorNum) + ".csv", "wb") ff.close() readyPIDcalc = False while (True): readytemp = False while parent_conn_temp.poll(): #Poll Get Temperature Process Pipe temp_C, tempSensorNum, elapsed = parent_conn_temp.recv() #non blocking receive from Get Temperature Process if temp_C == -99: print "Bad Temp Reading - retry" continue if (tempUnits == 'F'): temp = (9.0/5.0)*temp_C + 32 else: temp = temp_C temp_str = "%3.2f" % temp display.showTemperature(temp_str) readytemp = True if readytemp == True: if mode == "auto": temp_ma_list.append(temp) #smooth data temp_ma = 0.0 #moving avg init while (len(temp_ma_list) > num_pnts_smooth): temp_ma_list.pop(0) #remove oldest elements in list if (len(temp_ma_list) < num_pnts_smooth): for temp_pnt in temp_ma_list: temp_ma += temp_pnt temp_ma /= len(temp_ma_list) else: #len(temp_ma_list) == num_pnts_smooth for temp_idx in range(num_pnts_smooth): temp_ma += temp_ma_list[temp_idx] temp_ma /= num_pnts_smooth #print "len(temp_ma_list) = %d" % len(temp_ma_list) #print "Num Points smooth = %d" % num_pnts_smooth #print "temp_ma = %.2f" % temp_ma #print temp_ma_list #calculate PID every cycle if (readyPIDcalc == True): duty_cycle = pid.calcPID_reg4(temp_ma, set_point, True) #send to heat process every cycle parent_conn_heat.send([cycle_time, duty_cycle]) readyPIDcalc = False if mode == "boil": if (temp > boil_manage_temp) and (manage_boil_trigger == True): #do once manage_boil_trigger = False duty_cycle = boil_duty_cycle parent_conn_heat.send([cycle_time, duty_cycle]) #put current status in queue try: paramStatus = packParamGet(numTempSensors, myTempSensor.sensorNum, temp_str, tempUnits, elapsed, mode, cycle_time, duty_cycle, \ boil_duty_cycle, set_point, boil_manage_temp, num_pnts_smooth, k_param, i_param, d_param) statusQ.put(paramStatus) #GET request except Full: pass while (statusQ.qsize() >= 2): statusQ.get() #remove old status print "Current Temp: %3.2f deg %s, Heat Output: %3.1f%%" \ % (temp, tempUnits, duty_cycle) logdata(myTempSensor.sensorNum, temp, duty_cycle) readytemp == False #if only reading temperature (no temp control) if readOnly: continue while parent_conn_heat.poll(): #Poll Heat Process Pipe cycle_time, duty_cycle = parent_conn_heat.recv() #non blocking receive from Heat Process display.showDutyCycle(duty_cycle) readyPIDcalc = True readyPOST = False while conn.poll(): #POST settings - Received POST from web browser or Android device paramStatus = conn.recv() mode, cycle_time, duty_cycle_temp, boil_duty_cycle, set_point, boil_manage_temp, num_pnts_smooth, \ k_param, i_param, d_param = unPackParamInitAndPost(paramStatus) readyPOST = True if readyPOST == True: if mode == "auto": display.showAutoMode(set_point) print "auto selected" pid = PIDController.pidpy(cycle_time, k_param, i_param, d_param) #init pid duty_cycle = pid.calcPID_reg4(temp_ma, set_point, True) parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "boil": display.showBoilMode() print "boil selected" boil_duty_cycle = duty_cycle_temp duty_cycle = 100 #full power to boil manage temperature manage_boil_trigger = True parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "manual": display.showManualMode() print "manual selected" duty_cycle = duty_cycle_temp parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "off": display.showOffMode() print "off selected" duty_cycle = 0 parent_conn_heat.send([cycle_time, duty_cycle]) readyPOST = False time.sleep(.01)
def tempControlProc(myTempSensorNum, LCD, pinNum, readOnly, paramStatus, statusQ, conn): mode, cycle_time, duty_cycle, boil_duty_cycle, set_point, boil_manage_temp, num_pnts_smooth, \ k_param, i_param, d_param = unPackParamInitAndPost(paramStatus) #initialize LCD if LCD: ser = serial.Serial("/dev/ttyAMA0", 9600) ser.write("?BFF") time.sleep(.1) #wait 100msec ser.write("?f?a") ser.write("?y0?x00PID off ") ser.write("?y1?x00HLT:") ser.write("?y3?x00Heat: off ") ser.write("?D70609090600000000") #define degree symbol time.sleep(.1) #wait 100msec p = current_process() print 'Starting:', p.name, p.pid #Pipe to communicate with "Get Temperature Process" parent_conn_temp, child_conn_temp = Pipe() #Start Get Temperature Process ptemp = Process(name="gettempProc", target=gettempProc, args=(child_conn_temp, myTempSensorNum)) ptemp.daemon = True ptemp.start() #Pipe to communicate with "Heat Process" parent_conn_heat, child_conn_heat = Pipe() #Start Heat Process pheat = Process(name="heatProcGPIO", target=heatProcGPIO, args=(cycle_time, duty_cycle, pinNum, child_conn_heat)) pheat.daemon = True pheat.start() temp_ma_list = [] manage_boil_trigger = False tempUnits = xml_root.find('Temp_Units').text.strip() numTempSensors = 0 for tempSensorId in xml_root.iter('Temp_Sensor_Id'): numTempSensors += 1 temp_ma = 0.0 #overwrite log file for new data log ff = open("brewery" + str(myTempSensorNum) + ".csv", "wb") ff.close() while (True): readytemp = False while parent_conn_temp.poll(): #Poll Get Temperature Process Pipe temp_C, tempSensorNum, elapsed = parent_conn_temp.recv( ) #non blocking receive from Get Temperature Process if temp_C == -99: print "Bad Temp Reading - retry" continue if (tempUnits == 'F'): temp = (9.0 / 5.0) * temp_C + 32 else: temp = temp_C temp_str = "%3.2f" % temp if LCD: #write to LCD ser.write("?y1?x05") ser.write(temp_str) ser.write("?7") #degree time.sleep(.005) #wait 5msec if (tempUnits == 'F'): ser.write("F ") else: ser.write("C ") readytemp = True if readytemp == True: if mode == "auto": temp_ma_list.append(temp) #smooth data temp_ma = 0.0 #moving avg init while (len(temp_ma_list) > num_pnts_smooth): temp_ma_list.pop(0) #remove oldest elements in list if (len(temp_ma_list) < num_pnts_smooth): for temp_pnt in temp_ma_list: temp_ma += temp_pnt temp_ma /= len(temp_ma_list) else: #len(temp_ma_list) == num_pnts_smooth for temp_idx in range(num_pnts_smooth): temp_ma += temp_ma_list[temp_idx] temp_ma /= num_pnts_smooth #print "len(temp_ma_list) = %d" % len(temp_ma_list) #print "Num Points smooth = %d" % num_pnts_smooth #print "temp_ma = %.2f" % temp_ma #print temp_ma_list #calculate PID every cycle - always get latest temperature duty_cycle = pid.calcPID_reg4(temp_ma, set_point, True) #send to heat process every cycle parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "boil": if (temp > boil_manage_temp) and (manage_boil_trigger == True): #do once manage_boil_trigger = False duty_cycle = boil_duty_cycle parent_conn_heat.send([cycle_time, duty_cycle]) #put current status in queue try: paramStatus = packParamGet(numTempSensors, myTempSensorNum, temp_str, tempUnits, elapsed, mode, cycle_time, duty_cycle, \ boil_duty_cycle, set_point, boil_manage_temp, num_pnts_smooth, k_param, i_param, d_param) statusQ.put(paramStatus) #GET request except Full: pass while (statusQ.qsize() >= 2): statusQ.get() #remove old status print "Current Temp: %3.2f deg %s, Heat Output: %3.1f%%" \ % (temp, tempUnits, duty_cycle) logdata(myTempSensorNum, temp, duty_cycle) readytemp == False #if only reading temperature (no temp control) if readOnly: continue while parent_conn_heat.poll(): #Poll Heat Process Pipe cycle_time, duty_cycle = parent_conn_heat.recv( ) #non blocking receive from Heat Process if LCD: #write to LCD ser.write("?y2?x00Duty: ") ser.write("%3.1f" % duty_cycle) ser.write("% ") readyPOST = False while conn.poll( ): #POST settings - Received POST from web browser or Android device paramStatus = conn.recv() mode, cycle_time, duty_cycle_temp, boil_duty_cycle, set_point, boil_manage_temp, num_pnts_smooth, \ k_param, i_param, d_param = unPackParamInitAndPost(paramStatus) readyPOST = True if readyPOST == True: if mode == "auto": if LCD: ser.write("?y0?x00Auto Mode ") ser.write("?y1?x00HLT:") ser.write("?y3?x00Set To: ") ser.write("%3.1f" % set_point) ser.write("?7") #degree time.sleep(.005) #wait 5msec ser.write("F ") print "auto selected" pid = PIDController.pidpy(cycle_time, k_param, i_param, d_param) #init pid duty_cycle = pid.calcPID_reg4(temp_ma, set_point, True) parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "boil": if LCD: ser.write("?y0?x00Boil Mode ") ser.write("?y1?x00BK: ") ser.write("?y3?x00Heat: on ") print "boil selected" boil_duty_cycle = duty_cycle_temp duty_cycle = 100 #full power to boil manage temperature manage_boil_trigger = True parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "manual": if LCD: ser.write("?y0?x00Manual Mode ") ser.write("?y1?x00BK: ") ser.write("?y3?x00Heat: on ") print "manual selected" duty_cycle = duty_cycle_temp parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "off": if LCD: ser.write("?y0?x00PID off ") ser.write("?y1?x00HLT:") ser.write("?y3?x00Heat: off ") print "off selected" duty_cycle = 0 parent_conn_heat.send([cycle_time, duty_cycle]) readyPOST = False time.sleep(.01)
def tempControlProc(global_vars, mode, cycle_time, duty_cycle, set_point, k_param, i_param, d_param, statusQ, conn): p = current_process() logger = logging.getLogger('ispresso').getChild("tempControlProc") logger.info('Starting:' + p.name + ":" + str(p.pid)) try: parent_conn_temp, child_conn_temp = Pipe() ptemp = Process(name="gettempProc", target=gettempProc, args=( global_vars, child_conn_temp, )) ptemp.daemon = True ptemp.start() parent_conn_heat, child_conn_heat = Pipe() pheat = Process(name="heatProc", target=heatProc, args=(cycle_time, duty_cycle, child_conn_heat)) pheat.daemon = True pheat.start() pid = PIDController.pidpy(cycle_time, k_param, i_param, d_param) # init pid flush_cache = False last_temp_C = 0 while (True): time.sleep(0.1) readytemp = False while parent_conn_temp.poll(): temp_C, elapsed = parent_conn_temp.recv( ) # non blocking receive mode = scheduled_mode( mode ) # check to see if scheduler should fire on or off -- MOVING THIS as the OFF doesnt seem to fire.. if temp_C > 0: # the 1-wire sensor sometimes comes back with 0 -- need to fix that by holding on to last value. last_temp_C = temp_C else: temp_C = last_temp_C temp_F = (9.0 / 5.0) * temp_C + 32 temp_C_str = "%3.2f" % temp_C temp_F_str = "%3.2f" % temp_F temp_F_pretty = "%3.0f" % temp_F mem.lcd_connection.send( ['iSPRESSO ' + str(temp_F_pretty) + ' F', None, 0]) readytemp = True if readytemp == True: if mode == "auto": duty_cycle = pid.calcPID_reg4(temp_F, set_point, True) parent_conn_heat.send([cycle_time, duty_cycle]) GPIO.output(gpio_btn_heat_led, GPIO.HIGH) elif mode == "off": duty_cycle = 0 parent_conn_heat.send([cycle_time, duty_cycle]) GPIO.output(gpio_btn_heat_led, GPIO.LOW) if (not statusQ.full()): statusQ.put([ temp_F_str, elapsed, mode, cycle_time, duty_cycle, set_point, k_param, i_param, d_param ]) # GET request readytemp == False while parent_conn_heat.poll(): # non blocking receive cycle_time, duty_cycle = parent_conn_heat.recv() while conn.poll(): # POST settings mode, cycle_time, duty_cycle_temp, set_point, k_param, i_param, d_param, flush_cache = conn.recv( ) if flush_cache: mem.cache_day = None # this should force cache flush flush_cache = False mode = scheduled_mode( mode) # check to see if scheduler should fire on or off except: exc_type, exc_value, exc_traceback = sys.exc_info() logger.error(''.join('!! ' + line for line in traceback.format_exception( exc_type, exc_value, exc_traceback)))
def tempControlProc(tempQ, myRoaster, paramStatus, childParamConn): oldMode = '' tempUnits, mode, sampleTime, gasOutput, set_point, num_pnts_smooth, \ k_param, i_param, d_param = unPackParamInitAndPost(paramStatus) oldMode = mode p = current_process() print('Starting:', p.name, p.pid) # Pipe to communicate with "Heat Process" parentHeat, c = Pipe() # Start Heat Process # Fix this. What do sampleTime and gasOutput do here? pheat = Process(name="heatProcGPIO", target=heatProcGPIO, args=(c, sampleTime, gasOutput, myRoaster.getGasServo())) pheat.daemon = True pheat.start() # Get our PID ready readyPIDcalc = False # Temperature smoothing list tempMovingAverageList = [] tempMovingAverage = 0.0 slopeMovingAverageList = [] slopeMovingAverage = 0.0 while (True): readytemp = False tempSensorsParam = [] gasServoParam = [] while not tempQ.empty(): try: sensorInfo = tempQ.get() except e: print "tempQ was empty even when we said it wasn't. WTF." # This loop is not done. In here is where we have to figure out # which probe to pay attention to. # Rotation applies to probe 1. # Face down: π # Face up: 0..2*π # Battery side (esp8266 up): π/2 # Back side (esp8266 up): 1.5*π rotation = sensorInfo["position"]["rotation"] for sensor in sensorInfo["probes"]: temp_C = sensor["temp"] elapsed = sensor["elapsed"] / 1000.0 tempSensorNum = sensor["number"] if temp_C == -99: print("Bad Temp Reading - retry") continue if (tempUnits == 'F'): temp = (9.0 / 5.0) * temp_C + 32 else: temp = temp_C temp_str = "%3.2f" % temp readytemp = True tempSensorsParam.append( [tempSensorNum, tempSensorNum, temp_str]) if readytemp == True: if mode == "auto": tempMovingAverageList.append({ "temp": temp, "timestamp": time.time() }) # smooth data tempMovingAverage = 0.0 # moving avg init slopeMovingAverage = 0.0 while (len(tempMovingAverageList) > num_pnts_smooth): tempMovingAverageList.pop( 0) # remove oldest elements in list while (len(slopeMovingAverageList) > num_pnts_smooth - 1): slopeMovingAverageList.pop( 0 ) # slopeMovingAverage is one less because it's a diff for temp_pnt in tempMovingAverageList: tempMovingAverage += temp_pnt["temp"] tempMovingAverage /= len(tempMovingAverageList) # Now, compute the moving average of the slope # We need at least two values to compute a difference if len(tempMovingAverageList) > 1: i = 0 while i < len(tempMovingAverageList) - 1: diff = tempMovingAverageList[ i + 1]["temp"] - tempMovingAverageList[i]["temp"] slope = diff / ( tempMovingAverageList[i + 1]["timestamp"] - tempMovingAverageList[i]["timestamp"]) slopeMovingAverage = +slope i += 1 slopeMovingAverage /= len(tempMovingAverageList) # print "len(tempMovingAverageList) = %d" % len(tempMovingAverageList) # print "Num Points smooth = %d" % num_pnts_smooth # print "tempMovingAverage = %.2f" % tempMovingAverage # print tempMovingAverageList # calculate PID every cycle if (readyPIDcalc == True): gasOutput = pid.calcPID_reg4(slopeMovingAverage, set_point, True) # send to heat process every cycle if not oldMode == mode: myRoaster.getGasServo().setToSafeLow() print "%s changing to %s" % (oldMode, mode) oldMode = mode parentHeat.send([sampleTime, gasOutput]) readyPIDcalc = False gasServoParam = [ myRoaster.getGasServo().getServoId(), myRoaster.getGasServo().getSafeLow(), gasOutput ] # put current status in queue try: paramStatus = packParamGet(temp_str, tempUnits, elapsed, mode, sampleTime, gasOutput, \ set_point, num_pnts_smooth, k_param, i_param, d_param,tempSensorsParam, gasServoParam, rotation) statusQ.put(paramStatus) #GET request except Full: pass while (statusQ.qsize() >= 2): statusQ.get() #remove old status logdata(tempSensorNum, temp, gasOutput) if DEBUG: print("Current Temp: %3.2f deg %s, Heat Output: %3.1f%%" \ % (temp, tempUnits, gasOutput)) while parentHeat.poll(): # Poll Heat Process Pipe sampleTime, gasOutput = parentHeat.recv( ) #non blocking receive from Heat Process readyPIDcalc = True # Pick up any environment changes readyPOST = False while childParamConn.poll( ): #POST settings - Received POST from web browser or Android device paramStatus = childParamConn.recv() tempUnits, mode, sampleTime, gasOutput_temp, set_point, num_pnts_smooth, \ k_param, i_param, d_param = unPackParamInitAndPost(paramStatus) readyPOST = True if readyPOST == True: if mode == "auto": print("auto selected") pid = PIDController.pidpy(sampleTime, k_param, i_param, d_param) #init pid gasOutput = pid.calcPID_reg4(tempMovingAverage, set_point, True) # always zero out to lowest safe low before enabled modes if not oldMode == mode: myRoaster.getGasServo().setToSafeLow() parentHeat.send([sampleTime, gasOutput]) if mode == "manual": print("manual selected (%s and %s)" % (oldMode, mode)) gasOutput = gasOutput_temp # always zero out to lowest safe low before enabled modes if not oldMode == mode: print "setting to safeLow" myRoaster.getGasServo().setToSafeLow() parentHeat.send([sampleTime, gasOutput]) if mode == "off": print("off selected") # We don't care. Off is off. Always set to off. myRoaster.getGasServo().setOff() oldMode = mode readyPOST = False time.sleep(0.01)
def tempControlProc(mode, cycle_time, duty_cycle, set_point, k_param, i_param, d_param, statusQ, conn): #initialize LCD ser = serial.Serial("/dev/ttyAMA0", 9600) ser.write("?BFF") time.sleep(.1) #wait 100msec ser.write("?f?a") ser.write("?y0?x00PID off ") ser.write("?y1?x00HLT:") ser.write("?y3?x00Heat: off ") ser.write("?D70609090600000000") #define degree symbol time.sleep(.1) #wait 100msec p = current_process() print 'Starting:', p.name, p.pid parent_conn_temp, child_conn_temp = Pipe() ptemp = Process(name="gettempProc", target=gettempProc, args=(child_conn_temp, )) ptemp.daemon = True ptemp.start() parent_conn_heat, child_conn_heat = Pipe() pheat = Process(name="heatProc", target=heatProc, args=(cycle_time, duty_cycle, child_conn_heat)) pheat.daemon = True pheat.start() temp_F_ma_list = [] temp_F_ma = 0.0 while (True): readytemp = False while parent_conn_temp.poll(): temp_C, elapsed = parent_conn_temp.recv() #non blocking receive temp_F = (9.0 / 5.0) * temp_C + 32 temp_F_ma_list.append(temp_F) #print temp_F_ma_list #smooth temp data # if (len(temp_F_ma_list) == 1): temp_F_ma = temp_F_ma_list[0] elif (len(temp_F_ma_list) == 2): temp_F_ma = (temp_F_ma_list[0] + temp_F_ma_list[1]) / 2.0 elif (len(temp_F_ma_list) == 3): temp_F_ma = (temp_F_ma_list[0] + temp_F_ma_list[1] + temp_F_ma_list[2]) / 3.0 elif (len(temp_F_ma_list) == 4): temp_F_ma = (temp_F_ma_list[0] + temp_F_ma_list[1] + temp_F_ma_list[2] + temp_F_ma_list[3]) / 4.0 else: temp_F_ma = (temp_F_ma_list[0] + temp_F_ma_list[1] + temp_F_ma_list[2] + temp_F_ma_list[3] + \ temp_F_ma_list[4]) / 5.0 temp_F_ma_list.pop(0) #remove oldest element in list #print "Temp F MA %.2f" % temp_F_ma temp_C_str = "%3.2f" % temp_C temp_F_str = "%3.2f" % temp_F ser.write("?y1?x05") ser.write(temp_F_str) #ser.write("?y1?x10") ser.write("?7") #degree time.sleep(.005) #wait 5msec ser.write("F ") readytemp = True if readytemp == True: if mode == "auto": #calculate PID every cycle - alwyas get latest temp #duty_cycle = pid.calcPID(float(temp), set_point, True) #set_point_C = (5.0/9.0)*(set_point - 32) print "Temp F MA %.2f" % temp_F_ma duty_cycle = pid.calcPID_reg4(temp_F_ma, set_point, True) #send to heat process every cycle parent_conn_heat.send([cycle_time, duty_cycle]) if (not statusQ.full()): statusQ.put([ temp_F_str, elapsed, mode, cycle_time, duty_cycle, set_point, k_param, i_param, d_param ]) #GET request readytemp == False while parent_conn_heat.poll(): #non blocking receive cycle_time, duty_cycle = parent_conn_heat.recv() ser.write("?y2?x00Duty: ") ser.write("%3.1f" % duty_cycle) ser.write("% ") readyPOST = False while conn.poll(): #POST settings mode, cycle_time, duty_cycle_temp, set_point, k_param, i_param, d_param = conn.recv( ) readyPOST = True if readyPOST == True: if mode == "auto": ser.write("?y0?x00Auto Mode ") ser.write("?y1?x00HLT:") ser.write("?y3?x00Set To: ") ser.write("%3.1f" % set_point) ser.write("?7") #degree time.sleep(.005) #wait 5msec ser.write("F ") print "auto selected" #pid = PIDController.PID(cycle_time, k_param, i_param, d_param) #init pid #duty_cycle = pid.calcPID(float(temp), set_point, True) pid = PIDController.pidpy(cycle_time, k_param, i_param, d_param) #init pid #set_point_C = (5.0/9.0)*(set_point - 32) duty_cycle = pid.calcPID_reg4(temp_F_ma, set_point, True) parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "manual": ser.write("?y0?x00Manual Mode ") ser.write("?y1?x00BK: ") ser.write("?y3?x00Heat: on ") print "manual selected" duty_cycle = duty_cycle_temp parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "off": ser.write("?y0?x00PID off ") ser.write("?y1?x00HLT:") ser.write("?y3?x00Heat: off ") print "off selected" duty_cycle = 0 parent_conn_heat.send([cycle_time, duty_cycle]) readyPOST = False time.sleep(.01)
def tempControlProc(configFile, num, mode, cycle_time, duty_cycle, boil_duty_cycle, set_point, boil_manage_temp, num_pnts_smooth, k_param, i_param, d_param, statusQ, conn): initGlobalConfig(configFile) if useLCD: # initialize LCD ser = serial.Serial("/dev/ttyAMA0", 9600) ser.write("?BFF") time.sleep(.1) # wait 100msec ser.write("?f?a") ser.write("?y0?x00PID off ") ser.write("?y1?x00HLT:") ser.write("?y3?x00Heat: off ") ser.write("?D70609090600000000") # define degree symbol time.sleep(.1) # wait 100msec p = current_process() print 'Starting Controller ', num, ':', p.name, p.pid # Pipe to communicate with "Get Temperature Process" parent_conn_temp, child_conn_temp = Pipe() # Start Get Temperature Process ptemp = Process(name="gettempProc", target=gettempProc, args=(configFile, num, child_conn_temp,)) ptemp.daemon = True ptemp.start() # Pipe to communicate with "Heat Process" parent_conn_heat, child_conn_heat = Pipe() # Start Heat Process pheat = Process(name="heatProcGeneric", target=heatProcGeneric, args=(configFile, num, cycle_time, duty_cycle, child_conn_heat)) pheat.daemon = True pheat.start() temp_F_ma_list = [] manage_boil_trigger = False elapsed = 0.0 while (True): readytemp = False if ptemp.is_alive() == False: # switch off if temperature process fails to deliver data parent_conn_heat.send([cycle_time, 0]) print "Emergency Stop, no temperature" time.sleep(2) sys.exit() if pheat.is_alive() == False: print "Emergency Stop, no heater" sys.exit() while parent_conn_temp.poll(): # Poll Get Temperature Process Pipe temp_C, elapsedMeasurement = parent_conn_temp.recv() # non blocking receive from Get Temperature Process elapsed = elapsed + float(elapsedMeasurement) if temp_C == -99: print "Bad Temp Reading - retry" continue temp_F = (9.0 / 5.0) * temp_C + 32 temp_F_ma_list.append(temp_F) # smooth data temp_F_ma = 0.0 # moving avg init while (len(temp_F_ma_list) > num_pnts_smooth): temp_F_ma_list.pop(0) # remove oldest elements in list if (len(temp_F_ma_list) < num_pnts_smooth): for temp_pnt in temp_F_ma_list: temp_F_ma += temp_pnt temp_F_ma /= len(temp_F_ma_list) else: # len(temp_F_ma_list) == num_pnts_smooth for temp_idx in range(num_pnts_smooth): temp_F_ma += temp_F_ma_list[temp_idx] temp_F_ma /= num_pnts_smooth # print "len(temp_F_ma_list) = %d" % len(temp_F_ma_list) # print "Num Points smooth = %d" % num_pnts_smooth # print "temp_F_ma = %.2f" % temp_F_ma # print temp_F_ma_list temp_C_str = "%3.2f" % temp_C temp_F_str = "%3.2f" % temp_F # write to LCD if useLCD: ser.write("?y1?x05") ser.write(temp_F_str) ser.write("?7") # degree time.sleep(.005) # wait 5msec ser.write("F ") readytemp = True if readytemp == True: if mode == "auto": # calculate PID every cycle - always get latest temperature # print "Temp F MA %.2f" % temp_F_ma duty_cycle = pid.calcPID_reg4(temp_F_ma, set_point, True) # send to heat process every cycle parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "boil": if (temp_F > boil_manage_temp) and (manage_boil_trigger == True): # do once manage_boil_trigger = False duty_cycle = boil_duty_cycle parent_conn_heat.send([cycle_time, duty_cycle]) # put current status in queue try: statusQ.put([temp_F_str, elapsed, mode, cycle_time, duty_cycle, set_point, \ boil_manage_temp, num_pnts_smooth, k_param, i_param, d_param]) # GET request except Queue.Full: pass while (statusQ.qsize() >= 2): statusQ.get() # remove old status # print "Temp: %3.2f deg F, Heat Output: %3.1f%% %s %f" % (temp_F, duty_cycle, mode, boil_manage_temp) readytemp == False while parent_conn_heat.poll(): # Poll Heat Process Pipe cycle_time, duty_cycle = parent_conn_heat.recv() # non blocking receive from Heat Process # write to LCD if useLCD: ser.write("?y2?x00Duty: ") ser.write("%3.1f" % duty_cycle) ser.write("% ") readyPOST = False while conn.poll(): # POST settings - Received POST from web browser or Android device mode, cycle_time, duty_cycle_temp, set_point, boil_manage_temp, num_pnts_smooth, k_param, i_param, d_param = conn.recv() readyPOST = True if readyPOST == True: if mode == "auto": if useLCD: ser.write("?y0?x00Auto Mode ") ser.write("?y1?x00HLT:") ser.write("?y3?x00Set To: ") ser.write("%3.1f" % set_point) ser.write("?7") # degree time.sleep(.005) # wait 5msec ser.write("F ") print "auto selected" pid = PIDController.pidpy(cycle_time, k_param, i_param, d_param) # init pid duty_cycle = pid.calcPID_reg4(temp_F_ma, set_point, True) if mode == "boil": if useLCD: ser.write("?y0?x00Boil Mode ") ser.write("?y1?x00BK: ") ser.write("?y3?x00Heat: on ") print "boil selected" boil_duty_cycle = duty_cycle_temp duty_cycle = 100 # full power to boil manage temperature manage_boil_trigger = True if mode == "manual": if useLCD: ser.write("?y0?x00Manual Mode ") ser.write("?y1?x00BK: ") ser.write("?y3?x00Heat: on ") print "manual selected" duty_cycle = duty_cycle_temp if mode == "off": if useLCD: ser.write("?y0?x00PID off ") ser.write("?y1?x00HLT:") ser.write("?y3?x00Heat: off ") print "off selected" duty_cycle = 0 parent_conn_heat.send([cycle_time, duty_cycle]) readyPOST = False time.sleep(.01)
def tempControlProc(statusQ, pinNum, conn): mode, cycle_time, duty_cycle, boil_duty_cycle, set_point, boil_manage_temp, num_pnts_smooth, \ k_param, i_param, d_param = unPackParam(param.status); p = current_process() print "Starting", p.name, p.pid # Connections and Pipes for getting the temperature parent_conn_temp, child_conn_temp = Pipe() ptemp = Process(name = "gettempProc", target=gettempProc, args=(child_conn_temp, 0)) ptemp.daemon = True ptemp.start() # Connections and Pipes for the heading parent_conn_heat, child_conn_heat = Pipe() print "Pin Number is:", pinNum print "cycle_time", cycle_time print "duty_cycle", duty_cycle pheat = Process(name = "heatProcGPIO", target=heatProcGPIO, args=(cycle_time, duty_cycle, pinNum, child_conn_heat)) pheat.daemon = True pheat.start() temp_ma_list = [] manage_boil_trigger = False readyPIDcalc = False while (True): readytemp = False while parent_conn_temp.poll(): temp_C, elapsed = parent_conn_temp.recv() if temp_C == -99: print "Bad Temp Reading - retry" continue temp_str = "%3.2f" % temp_C readytemp = True if readytemp: print "in ready temp, mode is: ", mode if mode == "Auto": print "in auto mode----****" temp_ma_list.append(temp_C) #smooth data temp_ma = 0.0 #moving avg init while (len(temp_ma_list) > num_pnts_smooth): temp_ma_list.pop(0) #remove oldest elements in list if (len(temp_ma_list) < num_pnts_smooth): for temp_pnt in temp_ma_list: temp_ma += temp_pnt temp_ma /= len(temp_ma_list) else: #len(temp_ma_list) == num_pnts_smooth for temp_idx in range(num_pnts_smooth): temp_ma += temp_ma_list[temp_idx] temp_ma /= num_pnts_smooth print "Check if readyPIDcalc is set to true: ", readyPIDcalc #calculate PID every cycle if (readyPIDcalc == True): print "Calculating the PID Cycle" print " -- temp_ma", temp_ma print " -- set_point", set_point pid = PIDController.pidpy(cycle_time, k_param, i_param, d_param) #init pid duty_cycle = pid.calcPID_reg4(temp_ma, set_point, True) #send to heat process every cycle parent_conn_heat.send([cycle_time, duty_cycle]) readyPIDcalc = False print "set readyPIDCalc = False" if mode == "boil": if (temp_C > boil_manage_temp) and (manage_boil_trigger == True): #do once manage_boil_trigger = False duty_cycle = boil_duty_cycle parent_conn_heat.send([cycle_time, duty_cycle]) print "Current Temp: %3.2f deg %s, Heat Output: %3.1f%%" % (temp_C, "C", duty_cycle) readytemp == False #if only reading temperature (no temp control) if readOnly: continue while parent_conn_heat.poll(): #Poll Heat Process Pipe cycle_time, duty_cycle = parent_conn_heat.recv() #non blocking receive from Heat Process readyPIDcalc = True print "set readyPIDCalc = True" readyPOST = False while conn.poll(): #POST settings - Received POST from web browser or Android device paramStatus = conn.recv() mode, cycle_time, duty_cycle_temp, boil_duty_cycle, set_point, boil_manage_temp, num_pnts_smooth, \ k_param, i_param, d_param = unPackParam(paramStatus) readyPost = True if readyPOST == True: if mode == "Auto": print "Auto selected" pid = PIDController.pidpy(cycle_time, k_param, i_param, d_param) #init pid duty_cycle = pid.calcPID_reg4(temp_ma, set_point, True) parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "Boil": print "Boil selected" boil_duty_cycle = duty_cycle_temp duty_cycle = 100 #full power to boil manage temperature manage_boil_trigger = True parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "manual": print "manual selected" duty_cycle = duty_cycle_temp parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "off": print "off selected" duty_cycle = 0 parent_conn_heat.send([cycle_time, duty_cycle]) readyPOST = False time.sleep(.01)
def tempControlProc(myTempSensorNum, LCD, pinNum, readOnly, paramStatus, statusQ, conn): mode, cycle_time, duty_cycle, boil_duty_cycle, set_point, boil_manage_temp, num_pnts_smooth, k_param, i_param, d_param = unPackParamInitAndPost( paramStatus ) # initialize LCD if LCD: ser = serial.Serial("/dev/ttyAMA0", 9600) ser.write("?BFF") time.sleep(0.1) # wait 100msec ser.write("?f?a") ser.write("?y0?x00PID off ") ser.write("?y1?x00HLT:") ser.write("?y3?x00Heat: off ") ser.write("?D70609090600000000") # define degree symbol time.sleep(0.1) # wait 100msec p = current_process() print "Starting:", p.name, p.pid # Pipe to communicate with "Get Temperature Process" parent_conn_temp, child_conn_temp = Pipe() # Start Get Temperature Process ptemp = Process(name="gettempProc", target=gettempProc, args=(child_conn_temp, myTempSensorNum)) ptemp.daemon = True ptemp.start() # Pipe to communicate with "Heat Process" parent_conn_heat, child_conn_heat = Pipe() # Start Heat Process pheat = Process(name="heatProcGPIO", target=heatProcGPIO, args=(cycle_time, duty_cycle, pinNum, child_conn_heat)) pheat.daemon = True pheat.start() temp_ma_list = [] manage_boil_trigger = False tempUnits = xml_root.find("Temp_Units").text.strip() numTempSensors = 0 for tempSensorId in xml_root.iter("Temp_Sensor_Id"): numTempSensors += 1 temp_ma = 0.0 # overwrite log file for new data log ff = open("brewery" + str(myTempSensorNum) + ".csv", "wb") ff.close() readyPIDcalc = False while True: readytemp = False while parent_conn_temp.poll(): # Poll Get Temperature Process Pipe temp_C, tempSensorNum, elapsed = ( parent_conn_temp.recv() ) # non blocking receive from Get Temperature Process if temp_C == -99: print "Bad Temp Reading - retry" continue if tempUnits == "F": temp = (9.0 / 5.0) * temp_C + 32 else: temp = temp_C temp_str = "%3.2f" % temp if LCD: # write to LCD ser.write("?y1?x05") ser.write(temp_str) ser.write("?7") # degree time.sleep(0.005) # wait 5msec if tempUnits == "F": ser.write("F ") else: ser.write("C ") readytemp = True if readytemp == True: if mode == "auto": temp_ma_list.append(temp) # smooth data temp_ma = 0.0 # moving avg init while len(temp_ma_list) > num_pnts_smooth: temp_ma_list.pop(0) # remove oldest elements in list if len(temp_ma_list) < num_pnts_smooth: for temp_pnt in temp_ma_list: temp_ma += temp_pnt temp_ma /= len(temp_ma_list) else: # len(temp_ma_list) == num_pnts_smooth for temp_idx in range(num_pnts_smooth): temp_ma += temp_ma_list[temp_idx] temp_ma /= num_pnts_smooth # print "len(temp_ma_list) = %d" % len(temp_ma_list) # print "Num Points smooth = %d" % num_pnts_smooth # print "temp_ma = %.2f" % temp_ma # print temp_ma_list # calculate PID every cycle if readyPIDcalc == True: duty_cycle = pid.calcPID_reg4(temp_ma, set_point, True) # send to heat process every cycle parent_conn_heat.send([cycle_time, duty_cycle]) readyPIDcalc = False if mode == "boil": if (temp > boil_manage_temp) and (manage_boil_trigger == True): # do once manage_boil_trigger = False duty_cycle = boil_duty_cycle parent_conn_heat.send([cycle_time, duty_cycle]) # put current status in queue try: paramStatus = packParamGet( numTempSensors, myTempSensorNum, temp_str, tempUnits, elapsed, mode, cycle_time, duty_cycle, boil_duty_cycle, set_point, boil_manage_temp, num_pnts_smooth, k_param, i_param, d_param, ) statusQ.put(paramStatus) # GET request except Full: pass while statusQ.qsize() >= 2: statusQ.get() # remove old status print "Current Temp: %3.2f deg %s, Heat Output: %3.1f%%" % (temp, tempUnits, duty_cycle) logdata(myTempSensorNum, temp, duty_cycle) readytemp == False # if only reading temperature (no temp control) if readOnly: continue while parent_conn_heat.poll(): # Poll Heat Process Pipe cycle_time, duty_cycle = parent_conn_heat.recv() # non blocking receive from Heat Process if LCD: # write to LCD ser.write("?y2?x00Duty: ") ser.write("%3.1f" % duty_cycle) ser.write("% ") readyPIDcalc = True readyPOST = False while conn.poll(): # POST settings - Received POST from web browser or Android device paramStatus = conn.recv() mode, cycle_time, duty_cycle_temp, boil_duty_cycle, set_point, boil_manage_temp, num_pnts_smooth, k_param, i_param, d_param = unPackParamInitAndPost( paramStatus ) readyPOST = True if readyPOST == True: if mode == "auto": if LCD: ser.write("?y0?x00Auto Mode ") ser.write("?y1?x00HLT:") ser.write("?y3?x00Set To: ") ser.write("%3.1f" % set_point) ser.write("?7") # degree time.sleep(0.005) # wait 5msec ser.write("F ") print "auto selected" pid = PIDController.pidpy(cycle_time, k_param, i_param, d_param) # init pid duty_cycle = pid.calcPID_reg4(temp_ma, set_point, True) parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "boil": if LCD: ser.write("?y0?x00Boil Mode ") ser.write("?y1?x00BK: ") ser.write("?y3?x00Heat: on ") print "boil selected" boil_duty_cycle = duty_cycle_temp duty_cycle = 100 # full power to boil manage temperature manage_boil_trigger = True parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "manual": if LCD: ser.write("?y0?x00Manual Mode ") ser.write("?y1?x00BK: ") ser.write("?y3?x00Heat: on ") print "manual selected" duty_cycle = duty_cycle_temp parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "off": if LCD: ser.write("?y0?x00PID off ") ser.write("?y1?x00HLT:") ser.write("?y3?x00Heat: off ") print "off selected" duty_cycle = 0 parent_conn_heat.send([cycle_time, duty_cycle]) readyPOST = False time.sleep(0.01)
def tempControlProc(myTempSensor, display, pinNum, readOnly, paramStatus, statusQ, subscribeQ, conn): mode, cycle_time, duty_cycle, dry_duty_cycle, set_point, dry_manage_temp, num_pnts_smooth, \ k_param, i_param, d_param ,option = param.unPackParamInitAndPost(paramStatus) p = current_process() print("Starting , {}, pid {}, param {}".format(p.name, p.pid, paramStatus)) #Pipe to communicate with "Get Temperature Process" parent_conn_temp, child_conn_temp = Pipe() #Start Get Temperature Process ptemp = Process(target=gettempProc, args=(myTempSensor, child_conn_temp)) ptemp.daemon = True ptemp.start() lck.acquire() print("Starting , {}, pid {}".format(ptemp.name, ptemp.pid)) lck.release() #Pipe to communicate with "Heat Process" parent_conn_heat, child_conn_heat = Pipe() #Start Heat Process pheat = Process(name="heatProcGPIO", target=heatProcGPIO, args=(cycle_time, duty_cycle, pinNum, child_conn_heat)) pheat.daemon = True pheat.start() lck.acquire() print " starting {} , pid {}, pin {},readOnly {}".format( pheat.name, pheat.pid, pinNum, readOnly) lck.release() #time interval to write to iot iottime = time.time() temp_ma_list = [] #MVA temp list manage_dry_trigger = True #False tempUnits = xml_root.find('Temp_Units').text.strip() temp_ma = 0.0 #MVA temp humidity = 0 #overwrite log file for new data log # ff = open("dryer" + str(myTempSensor.sensorNum) + ".csv", "wb") # ff.close() mode1 = None lastwrite = time.time() while (True): readytemp = False while parent_conn_temp.poll( ): #Poll Get Temperature Process Pipe. Return whether there is any data available to be read. temp_C, humidity, tempSensorNum, elapsed = parent_conn_temp.recv( ) #non blocking receive from Get Temperature Process. Return an object sent from the other end of the connection using if temp_C == -99: print "Bad Temp Reading - retry" continue if (tempUnits == 'F'): temp = (9.0 / 5.0) * temp_C + 32 else: temp = temp_C temp_str = "%3.2f" % temp #12.3456789 > 12.35 display.showTemperature(temp_str) readytemp = True if readytemp == True: lck.acquire() print "tempControlProc :readytemp {}, set_point {}, duty_cycle {}, pin {}, temp {}, mode {},numTempSensors {} ".format( readytemp, set_point, duty_cycle, pinNum, temp, mode, numTempSensors) lck.release() while (parent_conn_heat.poll()): #get last poll(1) 1sek blok cycle_time, duty_cycle = parent_conn_heat.recv() #get status from mqtt subsrciber if cert is not None: lck.acquire() print "tempControlProc getting message from IOT subscription" lck.release() try: while not queueSub.empty() or queueSub.get( block=False) == 'DONE': msg = queueSub.get( block=False) # Read from the queue and do nothing print "tempControlProc queueSub ", msg if (msg == 'DONE'): #print "tempControlProc DONE, pin {}".format(pinNum) break elif msg == "False": readOnly = True if mode1 is None: mode1 = mode mode = "stopped" duty_cycle = 0 parent_conn_heat.send([cycle_time, duty_cycle]) #print "tempControlProct queueSub readonly {}, mode {},mode1 {}, pin{}".format(readOnly, mode,mode1, pinNum) elif msg == "stopped": readOnly = True mode = "stopped" #print "tempControlProct queueSub readonly {}, mode {}, mode1 {},pin{}".format(readOnly, mode, mode1,pinNum) elif msg == "True": if mode1 is not None: mode = mode1 mode1 = None readOnly = False #print "tempControlProct queueSub readonly {}, mode {}, mode1 {}, pin{}".format(readOnly, mode, mode1,pinNum) break except Empty: pass if mode == "off": lck.acquire() print("stoped", (time.time() - stop)) lck.release() import offGPIO GPIO.cleanup() # this ensures a clean exit os.killpg(0, signal.SIGKILL) # kill all processes in my group if mode == "auto": temp_ma_list.append(temp) #smooth data temp_ma = 0.0 #moving temp avg init while (len(temp_ma_list) > num_pnts_smooth): temp_ma_list.pop(0) #remove oldest elements in list if (len(temp_ma_list) < num_pnts_smooth): for temp_pnt in temp_ma_list: temp_ma += temp_pnt temp_ma /= len(temp_ma_list) else: #len(temp_ma_list) == num_pnts_smooth for temp_idx in range(num_pnts_smooth): temp_ma += temp_ma_list[temp_idx] temp_ma /= num_pnts_smooth #print "len(temp_ma_list) = %d" % len(temp_ma_list) #print "Num Points smooth = %d" % num_pnts_smooth #print "temp_ma = %.2f" % temp_ma #print temp_ma_list #calculate PID every cycle if (readyPIDcalc == True): #https://www.raspberrypi.org/forums/viewtopic.php?f=35&t=62438&p=463458 #https://www.raspberrypi.org/forums/viewtopic.php?t=63714&p=471636 set_point = dry_manage_temp pid = PIDController.pidpy(cycle_time, k_param, i_param, d_param) #init pid duty_cycle = pid.calcPID_reg4( temp_ma, set_point, True) #ogrevalna stopnja cikla #send to heat process every cycle parent_conn_heat.send([cycle_time, duty_cycle]) # readyPIDcalc = False lck.acquire() print "tempControlProc : duty_cycle {}, k {}, i {}, d {},temp_ma {} ".format( duty_cycle, k_param, i_param, d_param, temp_ma) lck.release() if mode == "heating": if (temp >= dry_manage_temp): # and (manage_dry_trigger == True): #send 0% heat power manage_dry_trigger = False duty_cycle = 0 parent_conn_heat.send([cycle_time, duty_cycle]) elif ( temp < set_point - 4 ): #dry_manage_temp-4):# and (manage_dry_trigger == True): #send 100% heat power manage_dry_trigger = False duty_cycle = 100 parent_conn_heat.send([cycle_time, duty_cycle]) #2.0,100 elif ( temp <= set_point - 2 ): #dry_manage_temp-2):# and (manage_dry_trigger == True): #60% heat power to lower heater manage_dry_trigger = False if pinNum == 22: duty_cycle = 100 else: duty_cycle = 0 parent_conn_heat.send([cycle_time, duty_cycle]) #2.0,600 elif (temp < set_point ): #dry_manage_temp):# and (manage_dry_trigger == True): #send 0% heat power and 50% heat power to lower heater manage_dry_trigger = False if pinNum == 22: duty_cycle = 50 else: duty_cycle = 0 parent_conn_heat.send([cycle_time, duty_cycle]) #2.0,600 elif (temp >= set_point ): #dry_manage_temp):# and (manage_dry_trigger == True): #send 0% heat power to heater manage_dry_trigger = False duty_cycle = 0 parent_conn_heat.send([cycle_time, duty_cycle]) #2.0,600 #put current status in queue try: paramStatus = packParamGet(numTempSensors, myTempSensor.sensorNum, temp_str, tempUnits, elapsed, mode, cycle_time, duty_cycle, \ dry_duty_cycle, set_point, dry_manage_temp, num_pnts_smooth, k_param, i_param, d_param,option ) statusQ.put(paramStatus) #GET request except Full: pass while (statusQ.qsize() >= 2): statusQ.get() #remove old status # print "Current Temp: %3.2f deg %s, Heat Output: %3.1f%%" \ # % (temp, tempUnits, duty_cycle) logdata(myTempSensor.sensorNum, temp, duty_cycle) #senzorPin namesto Num readytemp == False #if mode is stopped and only reading temperature (no temp control) if mode == 'stopped' and readOnly: duty_cycle = 0 parent_conn_heat.send([cycle_time, duty_cycle]) if DEBUG: lck.acquire() print "loop continue, mode {}, Pin {}".format(mode, pinNum) lck.release() #if only reading temperature (no temp control) if readOnly: if DEBUG: lck.acquire() print "loop continue, readonly {}, Pin {}".format( readOnly, pinNum) lck.release() continue if getruntime() >= (dry_time * 60): lck.acquire() print "exit dtime {}> dry_time {} ".format( getruntime(), dry_time * 60) lck.release() GPIO.cleanup() # this ensures a clean exit os.killpg(0, signal.SIGKILL) # kill all processes in my group if time.time() - iottime > sleep and cert is not None: iottime = time.time() weight = 10 humidity = 10 mode0 = "'" + str(mode) + "'" mode0 = str(mode0) iot = iot_mqtt_publisher2(thing, cert) lck.acquire() print("Send to IOT from temp_control", thing, cert, round(temp), round(temp), mode0, set_point, round(humidity), round(weight), round(getruntime())) lck.release() iot.send(round(temp, 2), round(temp, 2), mode0, set_point, round(humidity, 2), round(weight, 2), round(getruntime(), 0)) # parent_connIOT.send([round(temp,2),round(temp,2),mode0,set_point,round(humidity,2),round(weight,2),round(getruntime(),0)]) print "Write pin {}, time {}, sleep {}".format( pinNum, time.time() - lastwrite, sleep) if pinNum == 22 and time.time() - lastwrite > sleep: #and temp > 0 tab = " " line = "{d}{t}{l}{t}{m}{t}{n}{t}{o}\r\n".format( d=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), l=(format(temp, '.2f')), m=(format(temp - 1, '.2f')), n=format(humidity, '.2f'), o=0, t=tab) lck.acquire() print("write {} to {}.csv".format(line, filename)) lck.release() with open(filename + ".csv", "a") as myfile: myfile.write(line) myfile.close() lastwrite = time.time() # print "next loop" # while parent_conn_heat.poll(): #Poll Heat Process Pipe # cycle_time, duty_cycle = parent_conn_heat.recv() #non blocking receive from Heat Process # display.showDutyCycle(duty_cycle) # print "tempControlProc parent_conn_heat",parent_conn_heat.poll(), cycle_time, duty_cycle # readyPIDcalc = True readyPOST = False while conn.poll( ): #POST settings - Received POST from web browser or Android device paramStatus = conn.recv() mode, cycle_time, duty_cycle, dry_duty_cycle, set_point, dry_manage_temp, num_pnts_smooth, \ k_param, i_param, d_param ,option = param.unPackParamInitAndPost(paramStatus) readyPOST = True if readyPOST == True: #print "tempControlProc POST conn_poll duty_cycle {}, pin {} ,mode {}, cycle_time {} ".format( duty_cycle, pinNum, mode, cycle_time) if mode == "auto": display.showAutoMode(set_point) lck.acquire() print "auto selected" lck.release() for pin in pinFanList: if not GPIO.input(pin): # returns 1 print "Fan started", pin GPIO.output(pin, ON) pid = PIDController.pidpy(cycle_time, k_param, i_param, d_param) #init pid duty_cycle = pid.calcPID_reg4(temp_ma, set_point, True) parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "heating": display.showDryMode() lck.acquire() print "heating selected" lck.release() for pin in pinFanList: if not GPIO.input(pin): # returns 1 print "Fan started", pin GPIO.output(pin, ON) # dry_duty_cycle = duty_cycle_temp duty_cycle = dry_duty_cycle #100 #full power to dry manage temperature manage_dry_trigger = True parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "manual": display.showManualMode() lck.acquire() print "manual selected" lck.release() for pin in pinFanList: if GPIO.input(pin): # returns 1 print "Fan started", pin GPIO.output(pin, HIGH) duty_cycle = dry_duty_cycle parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "off": display.showOffMode() lck.acquire() print "off selected" lck.release() duty_cycle = 0 readonly = True parent_conn_heat.send([cycle_time, duty_cycle]) if mode == "stopped": display.showOffMode() lck.acquire() print "stop selected" lck.release() GPIO.output(piNum, GPIO.LOW) for pin in pinFanList: print "Fan stopped", pin GPIO.output(pin, LOW) duty_cycle = 0 parent_conn_heat.send([cycle_time, duty_cycle]) readyPOST = False time.sleep(.01)