succd: add additional safety interlocks

This commit is contained in:
zdmx 2024-09-27 22:29:56 +02:00
parent f7752922c2
commit d3391b28ec
3 changed files with 66 additions and 3 deletions

View file

@ -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{}

View file

@ -17,7 +17,10 @@ type daemon struct {
// Pirani gauge.
adcPirani adc
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.

View file

@ -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
}