simplify kiln-tuner, fix docs

This commit is contained in:
jbruce 2022-11-03 08:57:58 -09:00
parent 62efd5cde5
commit 1abeac4f4e
3 changed files with 54 additions and 39 deletions

View File

@ -94,10 +94,12 @@ If you're done playing around with simulations and want to deploy the code on a
All parameters are defined in config.py, review/change to your mind's content.
You should change, test, and verify PID parameters in config.py. Here is a [PID Tuning Guide](https://github.com/jbruce12000/kiln-controller/blob/master/docs/pid_tuning.md). There is also an [autotuner](https://github.com/jbruce12000/kiln-controller/blob/master/docs/ziegler_tuning.md). Be patient with tuning. No tuning is perfect across a wide temperature range.
You should change, test, and verify PID parameters in config.py. You need to read through config.py carefully to understand each setting.
You may want to change the configuration parameter **sensor_time_wait**. It's the duty cycle for the entire system. It's set to two seconds by default which means that a decision is made every 2s about whether to turn on relay[s] and for how long. If you use mechanical relays, you may want to increase this. At 2s, my SSR switches 11,000 times in 13 hours.
You should change **temp_scale** to either f for Farenheit or c for Celcius.
## Testing
After you've completed connecting all the hardware together, there are scripts to test the thermocouple and to test the output to the solid state relay. Read the scripts below and then start your testing. First, activate the virtual environment like so...
@ -116,6 +118,10 @@ and you can use this script to examine each pin's state including input/output/v
$ ./gpioreadall.py
## PID Tuning
Run the [autotuner](https://github.com/jbruce12000/kiln-controller/blob/master/docs/ziegler_tuning.md). It will heat your kiln to 400, pass that, and then once it cools back down to 400, it will calculate PID values to copy into config.py. No tuning is perfect across a wide temperature range. Here is a [PID Tuning Guide](https://github.com/jbruce12000/kiln-controller/blob/master/docs/pid_tuning.md) if you end up having to manually tune.
## Usage
### Server Startup

View File

@ -28,7 +28,6 @@ listening_port = 8081
# This is used to calculate a cost estimate before a run. It's also used
# to produce the actual cost during a run. My kiln has three
# elements that when my switches are set to high, consume 9460 watts.
kwh_rate = 0.1319 # cost per kilowatt hour per currency_type to calculate cost to run job
kw_elements = 9.460 # if the kiln elements are on, the wattage in kilowatts
currency_type = "$" # Currency Symbol to show when calculating cost to run job
@ -99,10 +98,12 @@ sensor_time_wait = 2
# well with the simulated oven. You must tune them to work well with
# your specific kiln. Note that the integral pid_ki is
# inverted so that a smaller number means more integral action.
pid_kp = 25 # Proportional 25,200,200
pid_ki = 10 # Integral
pid_kd = 200 # Derivative
#pid_kp = 25 # Proportional 25,200,200
#pid_ki = 10 # Integral
#pid_kd = 200 # Derivative
pid_kp = 14.22801211254364
pid_ki = 4.747842807629315
pid_kd = 240.283966775251
########################################################################
#
@ -115,7 +116,7 @@ stop_integral_windup = True
########################################################################
#
# Simulation parameters
simulate = False
simulate = True
sim_t_env = 60.0 # deg C
sim_c_heat = 500.0 # J/K heat capacity of heat element
sim_c_oven = 5000.0 # J/K heat capacity of oven
@ -132,7 +133,6 @@ sim_R_ho_air = 0.05 # K/W " with internal air circulation
#
# If you change the temp_scale, all settings in this file are assumed to
# be in that scale.
temp_scale = "f" # c = Celsius | f = Fahrenheit - Unit to display
time_scale_slope = "h" # s = Seconds | m = Minutes | h = Hours - Slope displayed in temp_scale per time_scale_slope
time_scale_profile = "m" # s = Seconds | m = Minutes | h = Hours - Enter and view target time in time_scale_profile
@ -164,10 +164,10 @@ pid_control_window = 5 #degrees
# cheap thermocouple. Invest in a better thermocouple.
thermocouple_offset=0
# number of samples of temperature to average.
# If you suffer from the high temperature kiln issue and have set
# honour_theromocouple_short_errors to False,
# you will likely need to increase this (eg I use 40)
# number of samples of temperature to average over each duty cycle.
# The larger the number, the more load on the board. K type
# thermocouples have a precision of about 1/2 degree C. This
# averaging smooths out the stair step jumps of this imprecision.
temperature_average_samples = 40
# Thermocouple AC frequency filtering - set to True if in a 50Hz locale, else leave at False for 60Hz locale

View File

@ -6,18 +6,19 @@ import csv
import time
import argparse
def recordprofile(csvfile, targettemp):
try:
try:
sys.dont_write_bytecode = True
import config
sys.dont_write_bytecode = False
except ImportError:
except ImportError:
print("Could not import config file.")
print("Copy config.py.EXAMPLE to config.py and adapt it for your setup.")
exit(1)
def recordprofile(csvfile, targettemp):
script_dir = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0, script_dir + '/lib/')
@ -186,31 +187,39 @@ if __name__ == "__main__":
subparsers = parser.add_subparsers()
parser.set_defaults(mode='')
parser_profile = subparsers.add_parser('recordprofile', help='Record kiln temperature profile')
parser_profile.add_argument('csvfile', type=str, help="The CSV file to write to.")
parser_profile.add_argument('--targettemp', type=int, default=400, help="The target temperature to drive the kiln to (default 400).")
parser_profile.set_defaults(mode='recordprofile')
csvfile = "tuning.csv"
target = 400
if config.temp_scale.lower() == "c":
target = (target - 32)*5/9
tangentdivisor = 8
parser_zn = subparsers.add_parser('zn', help='Calculate Ziegler-Nicols parameters')
parser_zn.add_argument('csvfile', type=str, help="The CSV file to read from. Must contain two columns called time (time in seconds) and temperature (observed temperature)")
parser_zn.add_argument('--showplot', action='store_true', help="If set, also plot results (requires pyplot to be pip installed)")
parser_zn.add_argument('--tangentdivisor', type=float, default=8, help="Adjust the tangent calculation to fit better. Must be >= 2 (default 8).")
parser_zn.set_defaults(mode='zn')
# parser_profile = subparsers.add_parser('recordprofile', help='Record kiln temperature profile')
# parser_profile.add_argument('csvfile', type=str, help="The CSV file to write to.")
# parser_profile.add_argument('--targettemp', type=int, default=400, help="The target temperature to drive the kiln to (default 400).")
# parser_profile.set_defaults(mode='recordprofile')
#parser_zn = subparsers.add_parser('zn', help='Calculate Ziegler-Nicols parameters')
#parser_zn.add_argument('csvfile', type=str, help="The CSV file to read from. Must contain two columns called time (time in seconds) and temperature (observed temperature)")
#parser_zn.add_argument('--showplot', action='store_true', help="If set, also plot results (requires pyplot to be pip installed)")
#parser_zn.add_argument('--tangentdivisor', type=float, default=8, help="Adjust the tangent calculation to fit better. Must be >= 2 (default 8).")
#parser_zn.set_defaults(mode='zn')
args = parser.parse_args()
if args.mode == 'recordprofile':
recordprofile(args.csvfile, args.targettemp)
# default behavior is to record profile to csv file tuning.csv
# and then calculate pid values and print them
recordprofile(csvfile, target)
calculate(csvfile, tangentdivisor, False)
elif args.mode == 'zn':
if args.tangentdivisor < 2:
raise ValueError("tangentdivisor must be >= 2")
calculate(args.csvfile, args.tangentdivisor, args.showplot)
elif args.mode == '':
parser.print_help()
exit(1)
else:
raise NotImplementedError("Unknown mode %s" % args.mode)
#elif args.mode == 'zn':
# if args.tangentdivisor < 2:
# raise ValueError("tangentdivisor must be >= 2")
#
# calculate(args.csvfile, args.tangentdivisor, args.showplot)
#
# elif args.mode == '':
# parser.print_help()
# exit(1)
#
# else:
# raise NotImplementedError("Unknown mode %s" % args.mode)