From f3f0310c366c056a1fcad3ff23ddef87914bde72 Mon Sep 17 00:00:00 2001 From: rmie Date: Fri, 10 Nov 2017 21:02:42 +0100 Subject: [PATCH 1/4] add support for Ad849x thermoucouple amplifiers --- config_system/generator/generate.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/config_system/generator/generate.py b/config_system/generator/generate.py index c5b6a59c..472bd418 100644 --- a/config_system/generator/generate.py +++ b/config_system/generator/generate.py @@ -2075,7 +2075,17 @@ def option(conversion_config): def option(conversion_config): gen.add_aprinter_include('printer/thermistor/InterpolationTableThermistor_tables.h') return TemplateExpr('InterpolationTableThermistorService', ['InterpolationTableE3dPt100']) - + + @conversion_sel.option('Ad849xFormula') + def option(conversion_config): + gen.add_aprinter_include('printer/thermistor/Ad849xFormula.h') + return TemplateExpr('Ad849xFormulaService', [ + gen.add_float_config('{}HeaterTempOffsetVoltage'.format(name), conversion_config.get_float('OffsetVoltage')), + gen.add_float_config('{}HeaterTempSlope'.format(name), conversion_config.get_float('Slope')), + gen.add_float_config('{}HeaterTempMinTemp'.format(name), conversion_config.get_float('MinTemp')), + gen.add_float_config('{}HeaterTempMaxTemp'.format(name), conversion_config.get_float('MaxTemp')), + ]) + conversion = heater.do_selection('conversion', conversion_sel) for control in heater.enter_config('control'): From fe4b07eed22482b94d8740159822bf9346199fcd Mon Sep 17 00:00:00 2001 From: rmie Date: Fri, 10 Nov 2017 21:12:18 +0100 Subject: [PATCH 2/4] add support for Ad849x thermoucouple amplifiers --- aprinter/printer/thermistor/Ad849xFormula.h | 89 +++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 aprinter/printer/thermistor/Ad849xFormula.h diff --git a/aprinter/printer/thermistor/Ad849xFormula.h b/aprinter/printer/thermistor/Ad849xFormula.h new file mode 100644 index 00000000..ad36843e --- /dev/null +++ b/aprinter/printer/thermistor/Ad849xFormula.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2015 Ambroz Bizjak, Armin van der Togt and others + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef APRINTER_AD849X_FORMULA_H +#define APRINTER_AD849X_FORMULA_H + +#include +#include +#include + +namespace APrinter { + +template +class Ad849xFormula { + using Context = typename Arg::Context; + using Config = typename Arg::Config; + using FpType = typename Arg::FpType; + using Params = typename Arg::Params; + +public: + static bool const NegativeSlope = false; + + template + static auto TempToAdc (Temp) -> decltype(Temp()/Config::e(Params::Slope::i()) + Config::e(Params::OffsetVoltage::i())); + + static FpType adcToTemp (Context c, FpType adc) + { + if (!(adc <= APRINTER_CFG(Config, CAdcMaxTemp, c))) { + return INFINITY; + } + if (!(adc >= APRINTER_CFG(Config, CAdcMinTemp, c))) { + return -INFINITY; + } + return (adc - APRINTER_CFG(Config, COffsetVoltage, c)) * APRINTER_CFG(Config, CSlope, c); + } + +private: + using CAdcMinTemp = decltype(ExprCast(TempToAdc(Config::e(Params::MinTemp::i())))); + using CAdcMaxTemp = decltype(ExprCast(TempToAdc(Config::e(Params::MaxTemp::i())))); + using COffsetVoltage = decltype(ExprCast(Config::e(Params::OffsetVoltage::i()))); + using CSlope = decltype(ExprCast(Config::e(Params::Slope::i()))); + +public: + struct Object {}; + + using ConfigExprs = MakeTypeList; +}; + +APRINTER_ALIAS_STRUCT_EXT(Ad849xFormulaService, ( + APRINTER_AS_TYPE(OffsetVoltage), + APRINTER_AS_TYPE(Slope), + APRINTER_AS_TYPE(MinTemp), + APRINTER_AS_TYPE(MaxTemp) +), ( + APRINTER_ALIAS_STRUCT_EXT(Formula, ( + APRINTER_AS_TYPE(Context), + APRINTER_AS_TYPE(ParentObject), + APRINTER_AS_TYPE(Config), + APRINTER_AS_TYPE(FpType) + ), ( + using Params = Ad849xFormulaService; + APRINTER_DEF_INSTANCE(Formula, Ad849xFormula) + )) +)) + +} + +#endif From ea1a6205313857fe77b5c5f87a0fc903ac3bf9b0 Mon Sep 17 00:00:00 2001 From: rmie Date: Sun, 19 Nov 2017 11:07:24 +0100 Subject: [PATCH 3/4] generic naming --- ...d849xFormula.h => PositiveLinearFormula.h} | 35 +++++++++++++------ config_system/generator/generate.py | 10 +++--- 2 files changed, 29 insertions(+), 16 deletions(-) rename aprinter/printer/thermistor/{Ad849xFormula.h => PositiveLinearFormula.h} (70%) diff --git a/aprinter/printer/thermistor/Ad849xFormula.h b/aprinter/printer/thermistor/PositiveLinearFormula.h similarity index 70% rename from aprinter/printer/thermistor/Ad849xFormula.h rename to aprinter/printer/thermistor/PositiveLinearFormula.h index ad36843e..f72f6bac 100644 --- a/aprinter/printer/thermistor/Ad849xFormula.h +++ b/aprinter/printer/thermistor/PositiveLinearFormula.h @@ -29,10 +29,22 @@ #include #include +/* + * AD849x - K-Type thermocouple amplifier, eg. https://www.adafruit.com/product/1778 + * zero offset 1.25V, slope 5mV/K, ADC reference 3.3V + * ZeroAdcValue = 1.25V/3.3V = 0.379 + * AdcSlope = (0.005V/K)/3.3V = 1.515e-3 1/K + * + * MAX849x - K-Type thermocouple amplifier + * zero offset 0V, slope 5mV/K, ADC reference 3.3V + * ZeroAdcValue = 0 + * AdcSlope = 1.515e-3 1/K + */ + namespace APrinter { template -class Ad849xFormula { +class PositiveLinearFormula { using Context = typename Arg::Context; using Config = typename Arg::Config; using FpType = typename Arg::FpType; @@ -42,7 +54,8 @@ class Ad849xFormula { static bool const NegativeSlope = false; template - static auto TempToAdc (Temp) -> decltype(Temp()/Config::e(Params::Slope::i()) + Config::e(Params::OffsetVoltage::i())); + static auto TempToAdc (Temp) -> decltype(Temp()*Config::e(Params::AdcSlope::i()) + + Config::e(Params::ZeroAdcValue::i())); static FpType adcToTemp (Context c, FpType adc) { @@ -52,24 +65,24 @@ class Ad849xFormula { if (!(adc >= APRINTER_CFG(Config, CAdcMinTemp, c))) { return -INFINITY; } - return (adc - APRINTER_CFG(Config, COffsetVoltage, c)) * APRINTER_CFG(Config, CSlope, c); + return (adc - APRINTER_CFG(Config, CZeroAdcValue, c)) / APRINTER_CFG(Config, CAdcSlope, c); } private: using CAdcMinTemp = decltype(ExprCast(TempToAdc(Config::e(Params::MinTemp::i())))); using CAdcMaxTemp = decltype(ExprCast(TempToAdc(Config::e(Params::MaxTemp::i())))); - using COffsetVoltage = decltype(ExprCast(Config::e(Params::OffsetVoltage::i()))); - using CSlope = decltype(ExprCast(Config::e(Params::Slope::i()))); + using CZeroAdcValue = decltype(ExprCast(Config::e(Params::ZeroAdcValue::i()))); + using CAdcSlope = decltype(ExprCast(Config::e(Params::AdcSlope::i()))); public: struct Object {}; - using ConfigExprs = MakeTypeList; + using ConfigExprs = MakeTypeList; }; -APRINTER_ALIAS_STRUCT_EXT(Ad849xFormulaService, ( - APRINTER_AS_TYPE(OffsetVoltage), - APRINTER_AS_TYPE(Slope), +APRINTER_ALIAS_STRUCT_EXT(PositiveLinearFormulaService, ( + APRINTER_AS_TYPE(ZeroAdcValue), + APRINTER_AS_TYPE(AdcSlope), APRINTER_AS_TYPE(MinTemp), APRINTER_AS_TYPE(MaxTemp) ), ( @@ -79,8 +92,8 @@ APRINTER_ALIAS_STRUCT_EXT(Ad849xFormulaService, ( APRINTER_AS_TYPE(Config), APRINTER_AS_TYPE(FpType) ), ( - using Params = Ad849xFormulaService; - APRINTER_DEF_INSTANCE(Formula, Ad849xFormula) + using Params = PositiveLinearFormulaService; + APRINTER_DEF_INSTANCE(Formula, PositiveLinearFormula) )) )) diff --git a/config_system/generator/generate.py b/config_system/generator/generate.py index 472bd418..85b42fa2 100644 --- a/config_system/generator/generate.py +++ b/config_system/generator/generate.py @@ -2076,12 +2076,12 @@ def option(conversion_config): gen.add_aprinter_include('printer/thermistor/InterpolationTableThermistor_tables.h') return TemplateExpr('InterpolationTableThermistorService', ['InterpolationTableE3dPt100']) - @conversion_sel.option('Ad849xFormula') + @conversion_sel.option('PositiveLinearFormula') def option(conversion_config): - gen.add_aprinter_include('printer/thermistor/Ad849xFormula.h') - return TemplateExpr('Ad849xFormulaService', [ - gen.add_float_config('{}HeaterTempOffsetVoltage'.format(name), conversion_config.get_float('OffsetVoltage')), - gen.add_float_config('{}HeaterTempSlope'.format(name), conversion_config.get_float('Slope')), + gen.add_aprinter_include('printer/thermistor/PositiveLinearFormula.h') + return TemplateExpr('PositiveLinearFormulaService', [ + gen.add_float_config('{}HeaterTempZeroAdcValue'.format(name), conversion_config.get_float('ZeroAdcValue')), + gen.add_float_config('{}HeaterTempAdcSlope'.format(name), conversion_config.get_float('AdcSlope')), gen.add_float_config('{}HeaterTempMinTemp'.format(name), conversion_config.get_float('MinTemp')), gen.add_float_config('{}HeaterTempMaxTemp'.format(name), conversion_config.get_float('MaxTemp')), ]) From 09e19e43199ff67b6d3fe5e37c77fcd48647e4c6 Mon Sep 17 00:00:00 2001 From: rmie Date: Sun, 19 Nov 2017 12:40:09 +0100 Subject: [PATCH 4/4] warn about negativ slope and return INFINITY to prevent thermal runaway --- aprinter/printer/thermistor/PositiveLinearFormula.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/aprinter/printer/thermistor/PositiveLinearFormula.h b/aprinter/printer/thermistor/PositiveLinearFormula.h index f72f6bac..d9133fc9 100644 --- a/aprinter/printer/thermistor/PositiveLinearFormula.h +++ b/aprinter/printer/thermistor/PositiveLinearFormula.h @@ -28,6 +28,7 @@ #include #include #include +#include /* * AD849x - K-Type thermocouple amplifier, eg. https://www.adafruit.com/product/1778 @@ -59,6 +60,11 @@ class PositiveLinearFormula { static FpType adcToTemp (Context c, FpType adc) { + // prevent thermal runaway + if (0 >= APRINTER_CFG(Config, CAdcSlope, c)) { + Context::Printer::print_pgm_string(c, AMBRO_PSTR("//Error:AdcSlope must be positive\n")); + return INFINITY; + } if (!(adc <= APRINTER_CFG(Config, CAdcMaxTemp, c))) { return INFINITY; }