Beispiel #1
0
def create_temperature_control(name,
                               section,
                               thread,
                               hardwareOkSignal=None,
                               coolingFan=None,
                               hotendFan=None):
    tempSet = hal.newsig('%s-temp-set' % name, hal.HAL_FLOAT)
    tempMeas = hal.newsig('%s-temp-meas' % name, hal.HAL_FLOAT)
    tempInRange = hal.newsig('%s-temp-in-range' % name, hal.HAL_BIT)
    tempPwm = hal.newsig('%s-temp-pwm' % name, hal.HAL_FLOAT)
    tempPwmMax = hal.newsig('%s-temp-pwm-max' % name, hal.HAL_FLOAT)
    tempLimitMin = hal.newsig('%s-temp-limit-min' % name, hal.HAL_FLOAT)
    tempLimitMax = hal.newsig('%s-temp-limit-max' % name, hal.HAL_FLOAT)
    tempStandby = hal.newsig('%s-temp-standby' % name, hal.HAL_FLOAT)
    tempInLimit = hal.newsig('%s-temp-in-limit' % name, hal.HAL_BIT)
    tempThermOk = hal.newsig('%s-temp-therm-ok' % name, hal.HAL_BIT)
    error = hal.newsig('%s-error' % name, hal.HAL_BIT)
    active = hal.newsig('%s-active' % name, hal.HAL_BIT)

    tempPidPgain = hal.newsig('%s-temp-pid-Pgain' % name, hal.HAL_FLOAT)
    tempPidIgain = hal.newsig('%s-temp-pid-Igain' % name, hal.HAL_FLOAT)
    tempPidDgain = hal.newsig('%s-temp-pid-Dgain' % name, hal.HAL_FLOAT)
    tempPidMaxerrorI = hal.newsig('%s-temp-pid-maxerrorI' % name,
                                  hal.HAL_FLOAT)
    tempPidOut = hal.newsig('%s-temp-pid-out' % name, hal.HAL_FLOAT)
    tempPidBias = hal.newsig('%s-temp-pid-bias' % name, hal.HAL_FLOAT)
    tempRangeMin = hal.newsig('%s-temp-range-min' % name, hal.HAL_FLOAT)
    tempRangeMax = hal.newsig('%s-temp-range-max' % name, hal.HAL_FLOAT)
    noErrorIn = hal.newsig('%s-no-error-in' % name, hal.HAL_BIT)
    errorIn = hal.newsig('%s-error-in' % name, hal.HAL_BIT)

    tempPidBiasOut = tempPidBias
    # coolingFan compensation
    if coolingFan:
        tempPidFanBias = hal.newsig('%s-temp-pid-fan-bias' % name,
                                    hal.HAL_FLOAT)
        tempPidBiasOut = hal.newsig('%s-temp-pid-bias-out' % name,
                                    hal.HAL_FLOAT)

        scale = rt.newinst('scale', 'scale.%s-temp-pid-fan-bias' % name)
        hal.addf(scale.name, thread)
        scale.pin('in').link('%s.pwm' % coolingFan)
        scale.pin('out').link(tempPidFanBias)
        scale.pin('gain').set(c.find(section, 'FAN_BIAS'))

        sum2 = rt.newinst('sum2', 'sum2.%s-temp-pid-bias' % name)
        hal.addf(sum2.name, thread)
        sum2.pin('in0').link(tempPidBias)
        sum2.pin('in1').link(tempPidFanBias)
        sum2.pin('out').link(tempPidBiasOut)

    # PID
    pid = rt.newinst('pid', 'pid.%s' % name)
    hal.addf('%s.do-pid-calcs' % pid.name, thread)
    pid.pin('enable').link('emcmot-0-enable')  # motor enable
    pid.pin('feedback').link(tempMeas)
    pid.pin('command').link(tempSet)
    pid.pin('output').link(tempPidOut)
    pid.pin('maxoutput').link(tempPwmMax)
    pid.pin('bias').link(tempPidBias)
    pid.pin('Pgain').link(tempPidPgain)
    pid.pin('Igain').link(tempPidIgain)
    pid.pin('Dgain').link(tempPidDgain)
    pid.pin('maxerrorI').link(tempPidMaxerrorI)

    # Limit heater PWM to positive values
    # PWM mimics hm2 implementation, which generates output for negative values
    limit1 = rt.newinst('limit1', 'limit.%s-temp-heaterl' % name)
    hal.addf(limit1.name, thread)
    limit1.pin('in').link(tempPidOut)
    limit1.pin('out').link(tempPwm)
    limit1.pin('min').set(0.0)
    limit1.pin('max').link(tempPwmMax)

    # Temperature checking
    sum2 = rt.newinst('sum2', 'sum2.%s-temp-range-pos' % name)
    hal.addf(sum2.name, thread)
    sum2.pin('in0').link(tempSet)
    sum2.pin('in1').set(c.find(section, 'TEMP_RANGE_POS_ERROR'))
    sum2.pin('out').link(tempRangeMax)

    sum2 = rt.newinst('sum2', 'sum2.%s-temp-range-neg' % name)
    hal.addf(sum2.name, thread)
    sum2.pin('in0').link(tempSet)
    sum2.pin('in1').set(c.find(section, 'TEMP_RANGE_NEG_ERROR'))
    sum2.pin('out').link(tempRangeMin)

    #the output of this component will say if measured temperature is in range of set value
    wcomp = rt.newinst('wcomp', 'wcomp.%s-temp-in-range' % name)
    hal.addf(wcomp.name, thread)
    wcomp.pin('min').link(tempRangeMin)
    wcomp.pin('max').link(tempRangeMax)
    wcomp.pin('in').link(tempMeas)
    wcomp.pin('out').link(tempInRange)

    # limit the output temperature to prevent damage when thermistor is broken/removed
    wcomp = rt.newinst('wcomp', 'wcomp.%s-temp-in-limit' % name)
    hal.addf(wcomp.name, thread)
    wcomp.pin('min').link(tempLimitMin)
    wcomp.pin('max').link(tempLimitMax)
    wcomp.pin('in').link(tempMeas)
    wcomp.pin('out').link(tempInLimit)

    # check the thermistor
    # net e0.temp.meas              => thermistor-check.e0.temp
    # net e0.temp.in-range          => not.e0-temp-range.in
    # net e0.temp.in-range_n        <= not.e0-temp-range.out
    # net e0.temp.in-range_n        => thermistor-check.e0.enable
    # net e0.heaterl                => thermistor-check.e0.pid
    # net e0.therm-ok               <= thermistor-check.e0.no-error

    # no error chain
    and3 = rt.newinst('andn', 'and3.%s-no-error-in' % name, pincount=3)
    hal.addf(and3.name, thread)
    and3.pin('in0').link(tempThermOk)
    and3.pin('in1').link(tempInLimit)
    if hardwareOkSignal:
        and3.pin('in2').link(hardwareOkSignal)
    else:
        and3.pin('in2').set(True)
    and3.pin('out').link(noErrorIn)

    tempThermOk.set(True)  # thermistor checking for now disabled

    notComp = rt.newinst('not', 'not.%s-error-in' % name)
    hal.addf(notComp.name, thread)
    notComp.pin('in').link(noErrorIn)
    notComp.pin('out').link(errorIn)

    safetyLatch = rt.newinst('safety_latch', 'safety-latch.%s-error' % name)
    hal.addf(safetyLatch.name, thread)
    safetyLatch.pin('error-in').link(errorIn)
    safetyLatch.pin('error-out').link(error)
    safetyLatch.pin('reset').link('estop-reset')
    safetyLatch.pin('threshold').set(500)  # 500ms error
    safetyLatch.pin('latching').set(True)

    # active chain
    comp = rt.newinst('comp', 'comp.%s-active' % name)
    hal.addf(comp.name, thread)
    comp.pin('in0').set(0.0001)
    comp.pin('hyst').set(0.0)
    comp.pin('in1').link(tempPwm)
    comp.pin('out').link(active)

    # Thermistor checking
    # setp thermistor-check.e0.wait 9.0
    # setp thermistor-check.e0.min-pid 1.5 # disable0.25
    # setp thermistor-check.e0.min-temp 1.5
    # net e0.pid.bias => thermistor-check.e0.bias

    # Hotend fan
    if hotendFan:
        comp = rt.newinst('comp', 'comp.%s-pwm-enable' % hotendFan)
        hal.addf(comp.name, thread)
        comp.pin('in0').set(c.find(section, 'HOTEND_FAN_THRESHOLD', 50.0))
        comp.pin('in1').link(tempMeas)
        comp.pin('hyst').set(c.find(section, 'HOTEND_FAN_HYST', 2.0))
        comp.pin('out').link('%s-pwm-enable' % hotendFan)

        hal.Signal('%s-pwm' % hotendFan).set(1.0)

    rcomps.create_temperature_rcomp(name)
    motion.setup_temperature_io(name)

    # init parameter signals
    tempLimitMin.set(c.find(section, 'TEMP_LIMIT_MIN'))
    tempLimitMax.set(c.find(section, 'TEMP_LIMIT_MAX'))
    tempStandby.set(c.find(section, 'TEMP_STANDBY'))
    tempPwmMax.set(c.find(section, 'PWM_MAX'))
    tempPidPgain.set(c.find(section, 'PID_PGAIN'))
    tempPidIgain.set(c.find(section, 'PID_IGAIN'))
    tempPidDgain.set(c.find(section, 'PID_DGAIN'))
    tempPidMaxerrorI.set(c.find(section, 'PID_MAXERRORI'))
    tempPidBias.set(c.find(section, 'PID_BIAS'))
Beispiel #2
0
def create_temperature_control(name, section, thread, hardwareOkSignal=None,
                               coolingFan=None, hotendFan=None):
    tempSet = hal.newsig('%s-temp-set' % name, hal.HAL_FLOAT)
    tempMeas = hal.newsig('%s-temp-meas' % name, hal.HAL_FLOAT)
    tempInRange = hal.newsig('%s-temp-in-range' % name, hal.HAL_BIT)
    tempPwm = hal.newsig('%s-temp-pwm' % name, hal.HAL_FLOAT)
    tempPwmMax = hal.newsig('%s-temp-pwm-max' % name, hal.HAL_FLOAT)
    tempLimitMin = hal.newsig('%s-temp-limit-min' % name, hal.HAL_FLOAT)
    tempLimitMax = hal.newsig('%s-temp-limit-max' % name, hal.HAL_FLOAT)
    tempStandby = hal.newsig('%s-temp-standby' % name, hal.HAL_FLOAT)
    tempInLimit = hal.newsig('%s-temp-in-limit' % name, hal.HAL_BIT)
    tempThermOk = hal.newsig('%s-temp-therm-ok' % name, hal.HAL_BIT)
    error = hal.newsig('%s-error' % name, hal.HAL_BIT)
    active = hal.newsig('%s-active' % name, hal.HAL_BIT)

    tempPidPgain = hal.newsig('%s-temp-pid-Pgain' % name, hal.HAL_FLOAT)
    tempPidIgain = hal.newsig('%s-temp-pid-Igain' % name, hal.HAL_FLOAT)
    tempPidDgain = hal.newsig('%s-temp-pid-Dgain' % name, hal.HAL_FLOAT)
    tempPidMaxerrorI = hal.newsig('%s-temp-pid-maxerrorI' % name, hal.HAL_FLOAT)
    tempPidOut = hal.newsig('%s-temp-pid-out' % name, hal.HAL_FLOAT)
    tempPidBias = hal.newsig('%s-temp-pid-bias' % name, hal.HAL_FLOAT)
    tempRangeMin = hal.newsig('%s-temp-range-min' % name, hal.HAL_FLOAT)
    tempRangeMax = hal.newsig('%s-temp-range-max' % name, hal.HAL_FLOAT)
    noErrorIn = hal.newsig('%s-no-error-in' % name, hal.HAL_BIT)
    errorIn = hal.newsig('%s-error-in' % name, hal.HAL_BIT)

    # reset set temperature when estop is cleared
    reset = rt.newinst('reset', 'reset.%s-temp-set' % name)
    hal.addf(reset.name, thread)
    reset.pin('reset-float').set(0.0)
    reset.pin('out-float').link(tempSet)
    reset.pin('rising').set(True)
    reset.pin('falling').set(False)
    reset.pin('trigger').link('estop-reset')

    tempPidBiasOut = tempPidBias
    # coolingFan compensation
    if coolingFan:
        tempPidFanBias = hal.newsig('%s-temp-pid-fan-bias' % name, hal.HAL_FLOAT)
        tempPidBiasOut = hal.newsig('%s-temp-pid-bias-out' % name, hal.HAL_FLOAT)

        scale = rt.newinst('scale', 'scale.%s-temp-pid-fan-bias' % name)
        hal.addf(scale.name, thread)
        scale.pin('in').link('%s.pwm' % coolingFan)
        scale.pin('out').link(tempPidFanBias)
        scale.pin('gain').set(c.find(section, 'FAN_BIAS'))

        sum2 = rt.newinst('sum2', 'sum2.%s-temp-pid-bias' % name)
        hal.addf(sum2.name, thread)
        sum2.pin('in0').link(tempPidBias)
        sum2.pin('in1').link(tempPidFanBias)
        sum2.pin('out').link(tempPidBiasOut)

    # PID
    pid = rt.newinst('pid', 'pid.%s' % name)
    hal.addf('%s.do-pid-calcs' % pid.name, thread)
    pid.pin('enable').link('emcmot-0-enable')  # motor enable
    pid.pin('feedback').link(tempMeas)
    pid.pin('command').link(tempSet)
    pid.pin('output').link(tempPidOut)
    pid.pin('maxoutput').link(tempPwmMax)
    pid.pin('bias').link(tempPidBias)
    pid.pin('Pgain').link(tempPidPgain)
    pid.pin('Igain').link(tempPidIgain)
    pid.pin('Dgain').link(tempPidDgain)
    pid.pin('maxerrorI').link(tempPidMaxerrorI)

    # Limit heater PWM to positive values
    # PWM mimics hm2 implementation, which generates output for negative values
    limit1 = rt.newinst('limit1', 'limit.%s-temp-heaterl' % name)
    hal.addf(limit1.name, thread)
    limit1.pin('in').link(tempPidOut)
    limit1.pin('out').link(tempPwm)
    limit1.pin('min').set(0.0)
    limit1.pin('max').link(tempPwmMax)

    # Temperature checking
    sum2 = rt.newinst('sum2', 'sum2.%s-temp-range-pos' % name)
    hal.addf(sum2.name, thread)
    sum2.pin('in0').link(tempSet)
    sum2.pin('in1').set(c.find(section, 'TEMP_RANGE_POS_ERROR'))
    sum2.pin('out').link(tempRangeMax)

    sum2 = rt.newinst('sum2', 'sum2.%s-temp-range-neg' % name)
    hal.addf(sum2.name, thread)
    sum2.pin('in0').link(tempSet)
    sum2.pin('in1').set(c.find(section, 'TEMP_RANGE_NEG_ERROR'))
    sum2.pin('out').link(tempRangeMin)

    #the output of this component will say if measured temperature is in range of set value
    wcomp = rt.newinst('wcomp', 'wcomp.%s-temp-in-range' % name)
    hal.addf(wcomp.name, thread)
    wcomp.pin('min').link(tempRangeMin)
    wcomp.pin('max').link(tempRangeMax)
    wcomp.pin('in').link(tempMeas)
    wcomp.pin('out').link(tempInRange)

    # limit the output temperature to prevent damage when thermistor is broken/removed
    wcomp = rt.newinst('wcomp', 'wcomp.%s-temp-in-limit' % name)
    hal.addf(wcomp.name, thread)
    wcomp.pin('min').link(tempLimitMin)
    wcomp.pin('max').link(tempLimitMax)
    wcomp.pin('in').link(tempMeas)
    wcomp.pin('out').link(tempInLimit)

    # check the thermistor
    # net e0.temp.meas              => thermistor-check.e0.temp
    # net e0.temp.in-range          => not.e0-temp-range.in
    # net e0.temp.in-range_n        <= not.e0-temp-range.out
    # net e0.temp.in-range_n        => thermistor-check.e0.enable
    # net e0.heaterl                => thermistor-check.e0.pid
    # net e0.therm-ok               <= thermistor-check.e0.no-error

    # no error chain
    and3 = rt.newinst('andn', 'and3.%s-no-error-in' % name, pincount=3)
    hal.addf(and3.name, thread)
    and3.pin('in0').link(tempThermOk)
    and3.pin('in1').link(tempInLimit)
    if hardwareOkSignal:
        and3.pin('in2').link(hardwareOkSignal)
    else:
        and3.pin('in2').set(True)
    and3.pin('out').link(noErrorIn)

    tempThermOk.set(True)  # thermistor checking for now disabled

    notComp = rt.newinst('not', 'not.%s-error-in' % name)
    hal.addf(notComp.name, thread)
    notComp.pin('in').link(noErrorIn)
    notComp.pin('out').link(errorIn)

    safetyLatch = rt.newinst('safety_latch', 'safety-latch.%s-error' % name)
    hal.addf(safetyLatch.name, thread)
    safetyLatch.pin('error-in').link(errorIn)
    safetyLatch.pin('error-out').link(error)
    safetyLatch.pin('reset').link('estop-reset')
    safetyLatch.pin('threshold').set(500)  # 500ms error
    safetyLatch.pin('latching').set(True)

    # active chain
    comp = rt.newinst('comp', 'comp.%s-active' % name)
    hal.addf(comp.name, thread)
    comp.pin('in0').set(0.0001)
    comp.pin('hyst').set(0.0)
    comp.pin('in1').link(tempPwm)
    comp.pin('out').link(active)

    # Thermistor checking
    # setp thermistor-check.e0.wait 9.0
    # setp thermistor-check.e0.min-pid 1.5 # disable0.25
    # setp thermistor-check.e0.min-temp 1.5
    # net e0.pid.bias => thermistor-check.e0.bias

    # Hotend fan
    if hotendFan:
        comp = rt.newinst('comp', 'comp.%s-pwm-enable' % hotendFan)
        hal.addf(comp.name, thread)
        comp.pin('in0').set(c.find(section, 'HOTEND_FAN_THRESHOLD', 50.0))
        comp.pin('in1').link(tempMeas)
        comp.pin('hyst').set(c.find(section, 'HOTEND_FAN_HYST', 2.0))
        comp.pin('out').link('%s-pwm-enable' % hotendFan)

        hal.Signal('%s-pwm' % hotendFan).set(1.0)

    rcomps.create_temperature_rcomp(name)
    motion.setup_temperature_io(name)

    # init parameter signals
    tempLimitMin.set(c.find(section, 'TEMP_LIMIT_MIN'))
    tempLimitMax.set(c.find(section, 'TEMP_LIMIT_MAX'))
    tempStandby.set(c.find(section, 'TEMP_STANDBY'))
    tempPwmMax.set(c.find(section, 'PWM_MAX'))
    tempPidPgain.set(c.find(section, 'PID_PGAIN'))
    tempPidIgain.set(c.find(section, 'PID_IGAIN'))
    tempPidDgain.set(c.find(section, 'PID_DGAIN'))
    tempPidMaxerrorI.set(c.find(section, 'PID_MAXERRORI'))
    tempPidBias.set(c.find(section, 'PID_BIAS'))
Beispiel #3
0
def create_temperature_control(name,
                               section,
                               thread,
                               hardwareOkSignal=None,
                               coolingFan=None,
                               hotendFan=None,
                               tclab_index=0):

    tempSet = hal.newsig('%s-temp-set' % name, hal.HAL_FLOAT)
    tempMeas = hal.newsig('%s-temp-meas' % name, hal.HAL_FLOAT)
    tempInRange = hal.newsig('%s-temp-in-range' % name, hal.HAL_BIT)
    tempInRangePre = hal.newsig('%s-temp-in-range-pre-check' % name,
                                hal.HAL_BIT)
    active = hal.newsig('%s-active' % name, hal.HAL_BIT)
    tempLimitMin = hal.newsig('%s-temp-limit-min' % name, hal.HAL_FLOAT)
    tempLimitMax = hal.newsig('%s-temp-limit-max' % name, hal.HAL_FLOAT)

    hal.Pin("hal_tclab.temperature-%s" % str(tclab_index)).link(tempMeas)
    hal.Pin("hal_tclab.setpoint-%s" % str(tclab_index)).link(tempSet)
    hal.Pin("hal_tclab.enable-%s" % str(tclab_index)).link(active)
    active.set(1)
    tempInLimit = hal.newsig('%s-temp-in-limit' % name, hal.HAL_BIT)
    tempThermOk = hal.newsig('%s-temp-therm-ok' % name, hal.HAL_BIT)
    error = hal.newsig('%s-error' % name, hal.HAL_BIT)

    tempPidPgain = hal.newsig('%s-temp-pid-Pgain' % name, hal.HAL_FLOAT)
    tempPidIgain = hal.newsig('%s-temp-pid-Igain' % name, hal.HAL_FLOAT)
    tempPidDgain = hal.newsig('%s-temp-pid-Dgain' % name, hal.HAL_FLOAT)
    tempPidMaxerrorI = hal.newsig('%s-temp-pid-maxerrorI' % name,
                                  hal.HAL_FLOAT)
    tempPidOut = hal.newsig('%s-temp-pid-out' % name, hal.HAL_FLOAT)
    tempPidBias = hal.newsig('%s-temp-pid-bias' % name, hal.HAL_FLOAT)
    tempRangeMin = hal.newsig('%s-temp-range-min' % name, hal.HAL_FLOAT)
    tempRangeMax = hal.newsig('%s-temp-range-max' % name, hal.HAL_FLOAT)
    noErrorIn = hal.newsig('%s-no-error-in' % name, hal.HAL_BIT)
    errorIn = hal.newsig('%s-error-in' % name, hal.HAL_BIT)

    sum2 = rt.newinst('sum2', 'sum2.%s-temp-range-pos' % name)
    hal.addf(sum2.name, thread)
    sum2.pin('in0').link(tempSet)
    sum2.pin('in1').set(c.find(section, 'TEMP_RANGE_POS_ERROR'))
    sum2.pin('out').link(tempRangeMax)

    sum2 = rt.newinst('sum2', 'sum2.%s-temp-range-neg' % name)
    hal.addf(sum2.name, thread)
    sum2.pin('in0').link(tempSet)
    sum2.pin('in1').set(c.find(section, 'TEMP_RANGE_NEG_ERROR'))
    sum2.pin('out').link(tempRangeMin)

    #the output of this component will say if measured temperature is in range of set value
    wcomp = rt.newinst('wcomp', 'wcomp.%s-temp-in-range' % name)
    hal.addf(wcomp.name, thread)
    wcomp.pin('min').link(tempRangeMin)
    wcomp.pin('max').link(tempRangeMax)
    wcomp.pin('in').link(tempMeas)
    wcomp.pin('out').link(tempInRangePre)

    notActive = hal.newsig('%s-not-active' % name, hal.HAL_BIT)
    activeNot = rt.newinst('not', 'not.%s.active-not' % name)
    hal.addf(activeNot.name, thread)
    activeNot.pin('in').link(active)
    activeNot.pin('out').link(notActive)

    or2 = rt.newinst('orn', 'or2.%s-check-temp-in-range' % name, pincount='2')
    hal.addf(or2.name, thread)
    or2.pin('in1').link(tempInRangePre)

    or2.pin('in0').link(notActive)
    or2.pin('out').link(tempInRange)

    # limit the output temperature to prevent damage when thermistor is broken/removed
    wcomp = rt.newinst('wcomp', 'wcomp.%s-temp-in-limit' % name)
    hal.addf(wcomp.name, thread)
    wcomp.pin('min').link(tempLimitMin)
    wcomp.pin('max').link(tempLimitMax)
    wcomp.pin('in').link(tempMeas)
    wcomp.pin('out').link(tempInLimit)

    rcomps.create_temperature_rcomp(name)
    motion.setup_temperature_io(name)
    tempLimitMax.set(c.find(section, "TEMP_LIMIT_MAX"))
    print("max set to", c.find(section, "TEMP_LIMIT_MAX"))
    tempLimitMin.set(c.find(section, "TEMP_LIMIT_MIN"))