th7/core/th7/service.go
2023-12-13 08:58:39 +00:00

111 lines
2.8 KiB
Go

package th7
import (
"log"
tdata "th7/data/thermocouple"
"th7/filter"
"th7/thermocouple"
"time"
)
const (
DurWaitBetweenChannel = 1 * time.Millisecond
DurWaitBetweenSample = 1 * time.Millisecond
DurWaitRestart = 1000 * time.Millisecond
)
// Continuously sample each configured channel, apply filter, and save result
// in a mutex controlled shared data object, that can be accessed at any time
// by a web-request or similar.
func startCacheService(t *TH7Adapter) {
// []core.Channel
data := t.data
// 2-dimensional f64 array of possibly diff sizes, to store samples
samples := make([][]float64, len(t.cfg.Channels))
// malloc each array
for i := range samples {
samples[i] = make([]float64, t.cfg.Channels[i].Filter.SampleSize)
}
for t.run {
for c := range t.cfg.Channels {
channel_id := t.cfg.Channels[c].Id
channel_gain := t.cfg.Channels[c].Gain
for i := 0; i < t.cfg.Channels[c].Filter.SampleSize; i++ {
// update vref table
t.pcbPort.UpdateTable()
measurement := t.pcbPort.ReadChannel(channel_id, channel_gain)
samples[c][i] = measurement
time.Sleep(DurWaitBetweenSample)
}
time.Sleep(DurWaitBetweenChannel)
}
// apply filter to each set of samples. First run will be noisy.
for i := range samples {
data[i].Value = filter.FilterByType(t.cfg.Channels[i].Filter.Type, samples[i], data[i].Value)
}
// read pcb temp and apply CJC
// the board temperature wont noticeably change for the ~300 ms of sampling
// at least compared to the TC error.
// so only reading pcb temp and applying cjc after this duration
// probably wont affect the readings.
pcb_temperature := t.pcbPort.ReadPCBTemp()
for k := range t.cfg.Channels {
ttype := t.cfg.Channels[k].Thermo
data[k].Id = t.cfg.Channels[k].Id
// if we can apply CJC with this configuration ...
if thermocouple.WithinTemperatureRange(ttype, pcb_temperature) {
cjc_uv, err := thermocouple.UV(ttype, pcb_temperature)
if err != nil {
log.Println("Error doing CJC", err)
cjc_uv = 0.0
}
data[k].Value += cjc_uv
}
// if the thermocouple unit is "None", it is for UV only.
// so do not convert it to a value using t/c polys
if t.cfg.Channels[k].Thermo != tdata.None {
new_value_c, err := thermocouple.C(ttype, data[k].Value)
if err != nil {
log.Println("Error converting UV to C", t.cfg.Channels[k].Id, data[k].Value)
new_value_c = data[k].Value
}
data[k].Value = new_value_c
// temp conv if any is applied ... add offset
data[k].Value += t.cfg.Channels[k].Offset
}
}
// update ratio table
table := t.pcbPort.GetTable()
t.mu.Lock() // LOCK
t.data = data
t.table.Pivdd = table.Pivdd
t.table.Vadj = table.Vadj
t.table.Vref = table.Vref
t.mu.Unlock() // UNLOCK
time.Sleep(DurWaitRestart)
}
}