thermocouple: Only shutdown on multiple consecutive sensor errors
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
ec5719585e
commit
51da02b7f8
|
@ -4,7 +4,7 @@
|
||||||
# Copyright (C) 2018 Kevin O'Connor <kevin@koconnor.net>
|
# Copyright (C) 2018 Kevin O'Connor <kevin@koconnor.net>
|
||||||
#
|
#
|
||||||
# This file may be distributed under the terms of the GNU GPLv3 license.
|
# This file may be distributed under the terms of the GNU GPLv3 license.
|
||||||
import math
|
import math, logging
|
||||||
from . import bus
|
from . import bus
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ from . import bus
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
REPORT_TIME = 0.300
|
REPORT_TIME = 0.300
|
||||||
|
MAX_INVALID_COUNT = 3
|
||||||
|
|
||||||
class SensorBase:
|
class SensorBase:
|
||||||
def __init__(self, config, chip_type, config_cmd=None, spi_mode=1):
|
def __init__(self, config, chip_type, config_cmd=None, spi_mode=1):
|
||||||
|
@ -47,9 +48,10 @@ class SensorBase:
|
||||||
self._report_clock = self.mcu.seconds_to_clock(REPORT_TIME)
|
self._report_clock = self.mcu.seconds_to_clock(REPORT_TIME)
|
||||||
self.mcu.add_config_cmd(
|
self.mcu.add_config_cmd(
|
||||||
"query_thermocouple oid=%u clock=%u rest_ticks=%u"
|
"query_thermocouple oid=%u clock=%u rest_ticks=%u"
|
||||||
" min_value=%u max_value=%u" % (
|
" min_value=%u max_value=%u max_invalid_count=%u" % (
|
||||||
self.oid, clock, self._report_clock,
|
self.oid, clock, self._report_clock,
|
||||||
self.min_sample_value, self.max_sample_value), is_init=True)
|
self.min_sample_value, self.max_sample_value,
|
||||||
|
MAX_INVALID_COUNT), is_init=True)
|
||||||
def _handle_spi_response(self, params):
|
def _handle_spi_response(self, params):
|
||||||
if params['fault']:
|
if params['fault']:
|
||||||
self.handle_fault(params['value'], params['fault'])
|
self.handle_fault(params['value'], params['fault'])
|
||||||
|
@ -60,7 +62,7 @@ class SensorBase:
|
||||||
last_read_time = self.mcu.clock_to_print_time(last_read_clock)
|
last_read_time = self.mcu.clock_to_print_time(last_read_clock)
|
||||||
self._callback(last_read_time, temp)
|
self._callback(last_read_time, temp)
|
||||||
def report_fault(self, msg):
|
def report_fault(self, msg):
|
||||||
self.printer.invoke_async_shutdown(msg)
|
logging.warn(msg)
|
||||||
|
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
|
@ -283,8 +285,8 @@ class MAX31865(SensorBase):
|
||||||
rtd_reference_r = config.getfloat('rtd_reference_r', 430., above=0.)
|
rtd_reference_r = config.getfloat('rtd_reference_r', 430., above=0.)
|
||||||
adc_to_resist = rtd_reference_r / float(MAX31865_ADC_MAX)
|
adc_to_resist = rtd_reference_r / float(MAX31865_ADC_MAX)
|
||||||
self.adc_to_resist_div_nominal = adc_to_resist / rtd_nominal_r
|
self.adc_to_resist_div_nominal = adc_to_resist / rtd_nominal_r
|
||||||
SensorBase.__init__(self, config, "MAX31865",
|
self.config_reg = self.build_spi_init(config)
|
||||||
self.build_spi_init(config))
|
SensorBase.__init__(self, config, "MAX31865", self.config_reg)
|
||||||
def handle_fault(self, adc, fault):
|
def handle_fault(self, adc, fault):
|
||||||
if fault & 0x80:
|
if fault & 0x80:
|
||||||
self.report_fault("Max31865 RTD input is disconnected")
|
self.report_fault("Max31865 RTD input is disconnected")
|
||||||
|
@ -303,6 +305,8 @@ class MAX31865(SensorBase):
|
||||||
self.report_fault("Max31865 Overvoltage or undervoltage fault")
|
self.report_fault("Max31865 Overvoltage or undervoltage fault")
|
||||||
if not fault & 0xfc:
|
if not fault & 0xfc:
|
||||||
self.report_fault("Max31865 Unspecified error")
|
self.report_fault("Max31865 Unspecified error")
|
||||||
|
# Attempt to clear the fault
|
||||||
|
self.spi.spi_send(self.config_reg)
|
||||||
def calc_temp(self, adc):
|
def calc_temp(self, adc):
|
||||||
adc = adc >> 1 # remove fault bit
|
adc = adc >> 1 # remove fault bit
|
||||||
R_div_nominal = adc * self.adc_to_resist_div_nominal
|
R_div_nominal = adc * self.adc_to_resist_div_nominal
|
||||||
|
|
|
@ -28,6 +28,7 @@ struct thermocouple_spi {
|
||||||
uint32_t min_value; // Min allowed ADC value
|
uint32_t min_value; // Min allowed ADC value
|
||||||
uint32_t max_value; // Max allowed ADC value
|
uint32_t max_value; // Max allowed ADC value
|
||||||
struct spidev_s *spi;
|
struct spidev_s *spi;
|
||||||
|
uint8_t max_invalid, invalid_count;
|
||||||
uint8_t chip_type, flags;
|
uint8_t chip_type, flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -75,11 +76,13 @@ command_query_thermocouple(uint32_t *args)
|
||||||
return;
|
return;
|
||||||
spi->min_value = args[3];
|
spi->min_value = args[3];
|
||||||
spi->max_value = args[4];
|
spi->max_value = args[4];
|
||||||
|
spi->max_invalid = args[5];
|
||||||
|
spi->invalid_count = 0;
|
||||||
sched_add_timer(&spi->timer);
|
sched_add_timer(&spi->timer);
|
||||||
}
|
}
|
||||||
DECL_COMMAND(command_query_thermocouple,
|
DECL_COMMAND(command_query_thermocouple,
|
||||||
"query_thermocouple oid=%c clock=%u rest_ticks=%u"
|
"query_thermocouple oid=%c clock=%u rest_ticks=%u"
|
||||||
" min_value=%u max_value=%u");
|
" min_value=%u max_value=%u max_invalid_count=%c");
|
||||||
|
|
||||||
static void
|
static void
|
||||||
thermocouple_respond(struct thermocouple_spi *spi, uint32_t next_begin_time
|
thermocouple_respond(struct thermocouple_spi *spi, uint32_t next_begin_time
|
||||||
|
@ -88,10 +91,13 @@ thermocouple_respond(struct thermocouple_spi *spi, uint32_t next_begin_time
|
||||||
sendf("thermocouple_result oid=%c next_clock=%u value=%u fault=%c",
|
sendf("thermocouple_result oid=%c next_clock=%u value=%u fault=%c",
|
||||||
oid, next_begin_time, value, fault);
|
oid, next_begin_time, value, fault);
|
||||||
/* check the result and stop if below or above allowed range */
|
/* check the result and stop if below or above allowed range */
|
||||||
if (value < spi->min_value || value > spi->max_value)
|
if (fault || value < spi->min_value || value > spi->max_value) {
|
||||||
try_shutdown("Thermocouple ADC out of range");
|
spi->invalid_count++;
|
||||||
if (fault)
|
if (spi->invalid_count < spi->max_invalid)
|
||||||
|
return;
|
||||||
try_shutdown("Thermocouple reader fault");
|
try_shutdown("Thermocouple reader fault");
|
||||||
|
}
|
||||||
|
spi->invalid_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in New Issue