From d3391b28ec9c8b88a521109b202353a5be878403 Mon Sep 17 00:00:00 2001 From: zdmx Date: Fri, 27 Sep 2024 22:29:56 +0200 Subject: [PATCH] succd: add additional safety interlocks --- succbone/succd/main.go | 1 + succbone/succd/process.go | 34 +++++++++++++++++++++++++++++++--- succbone/succd/ringbuffer.go | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 succbone/succd/ringbuffer.go diff --git a/succbone/succd/main.go b/succbone/succd/main.go index 32e5c17..2a03729 100644 --- a/succbone/succd/main.go +++ b/succbone/succd/main.go @@ -31,6 +31,7 @@ func main() { } d.aboveRough.threshold = float64(flagPressureThresholdRough) d.aboveHigh.threshold = float64(flagPressureThresholdHigh) + d.lastPressures = newRingbuffer() if flagFake { klog.Infof("Starting with fake peripherals") d.adcPirani = &fakeADC{} diff --git a/succbone/succd/process.go b/succbone/succd/process.go index a25aa26..466355a 100644 --- a/succbone/succd/process.go +++ b/succbone/succd/process.go @@ -17,7 +17,10 @@ type daemon struct { // Pirani gauge. adcPirani adc - failsafe bool + lastPressures ringbuffer + + failsafe bool + highPressure bool gpioDiffusionPump gpio gpioRoughingPump gpio @@ -122,7 +125,15 @@ func (d *daemon) processOnce(_ context.Context) error { d.aboveRough.process(float64(mbar)) d.aboveHigh.process(float64(mbar)) - if mbar < 4e-6 { + d.lastPressures.AddValue(mbar) + + // max rate of 1.0 in 500 ms because ringbuffer holds 5 values + if d.lastPressures.MaxMinDiff() > 1.0 { + if !d.failsafe { + d.failsafe = true + klog.Errorf("Pressure changed too fast; entering failsafe mode") + } + } else if mbar < 4e-6 { // Unrealistic result, Pirani probe probably disconnected. Failsafe mode. if !d.failsafe { d.failsafe = true @@ -131,13 +142,30 @@ func (d *daemon) processOnce(_ context.Context) error { } else { if d.failsafe { d.failsafe = false - klog.Infof("Pirani probe has been reconnected; quitting failsafe mode") + klog.Infof("Values are plausible again; quitting failsafe mode") + } + } + + if mbar >= 1e-1 { + if !d.highPressure { + d.highPressure = true + klog.Errorf("Pressure is too high; enabling diffusion pump lockout") + } + } else { + if d.highPressure { + d.highPressure = false + klog.Infof("Pressure is low enough for diffusion pump operation; quitting diffusion pump lockout") } } if d.failsafe { d.aboveRough.output = true d.aboveHigh.output = true + d.dpOn = false + } + + if d.highPressure { + d.dpOn = false } // Update relay outputs. diff --git a/succbone/succd/ringbuffer.go b/succbone/succd/ringbuffer.go new file mode 100644 index 0000000..76be63c --- /dev/null +++ b/succbone/succd/ringbuffer.go @@ -0,0 +1,34 @@ +package main + +type ringbuffer struct { + data []float32 + idx int +} + +func newRingbuffer() ringbuffer { + return ringbuffer { + data: make([]float32, 5), + idx: 0, + } +} + +func (rb *ringbuffer) AddValue(value float32) { + rb.data[rb.idx] = value; + rb.idx = (rb.idx + 1) % len(rb.data) +} + +func (rb *ringbuffer) MaxMinDiff() float32 { + min := rb.data[0] + max := rb.data[0] + + for _, val := range rb.data { + if val < min { + min = val + } + if val > max { + max = val + } + } + + return max - min +}