Compare commits

..

1 Commits

Author SHA1 Message Date
c1b183ddd5 steinhart_hart: Beta Parameter uom dimensions
The Beta Parameter is not dimensionless, and has unit Kelvin.
Incorporate that into the type system for better checks.
2024-08-06 16:31:40 +08:00
6 changed files with 19 additions and 30 deletions

View File

@ -45,7 +45,7 @@ There are several options for flashing Thermostat. DFU requires only a micro-USB
### dfu-util on Linux
* Install the DFU USB tool (dfu-util).
* Convert firmware from ELF to BIN: `llvm-objcopy -O binary target/thumbv7em-none-eabihf/release/thermostat thermostat.bin` (you can skip this step if using the BIN from Hydra)
* Convert firmware from ELF to BIN: `arm-none-eabi-objcopy -O binary thermostat thermostat.bin` (you can skip this step if using the BIN from Hydra)
* Connect to the Micro USB connector to Thermostat below the RJ45.
* Add jumper to Thermostat v2.0 across 2-pin jumper adjacent to JTAG connector.
* Cycle board power to put it in DFU update mode

8
flake.lock generated
View File

@ -2,16 +2,16 @@
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1722791413,
"narHash": "sha256-rCTrlCWvHzMCNcKxPE3Z/mMK2gDZ+BvvpEVyRM4tKmU=",
"lastModified": 1691421349,
"narHash": "sha256-RRJyX0CUrs4uW4gMhd/X4rcDG8PTgaaCQM5rXEJOx6g=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "8b5b6723aca5a51edf075936439d9cd3947b7b2c",
"rev": "011567f35433879aae5024fc6ec53f2a0568a6c4",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-24.05",
"ref": "nixos-23.05",
"repo": "nixpkgs",
"type": "github"
}

View File

@ -1,7 +1,7 @@
{
description = "Firmware for the Sinara 8451 Thermostat";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
inputs.nixpkgs.url = github:NixOS/nixpkgs/nixos-23.05;
inputs.rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs";
@ -47,7 +47,6 @@
'';
dontFixup = true;
auditable = false;
};
in {
packages.x86_64-linux = {
@ -62,8 +61,7 @@
devShells.x86_64-linux.default = pkgs.mkShellNoCC {
name = "thermostat-dev-shell";
packages = with pkgs; [
rust llvm
openocd dfu-util
rust openocd dfu-util
] ++ (with python3Packages; [
numpy matplotlib
]);

View File

@ -1,4 +1,4 @@
use core::marker::PhantomData;
use core::{cmp::max_by, marker::PhantomData};
use heapless::{consts::U2, Vec};
use num_traits::Zero;
use serde::{Serialize, Serializer};
@ -561,10 +561,9 @@ impl Channels {
}
pub fn current_abs_max_tec_i(&mut self) -> ElectricCurrent {
(0..CHANNELS)
.map(|channel| self.get_tec_i(channel).abs())
.max_by(|a, b| a.partial_cmp(b).unwrap_or(core::cmp::Ordering::Equal))
.unwrap()
max_by(self.get_tec_i(0).abs(),
self.get_tec_i(1).abs(),
|a, b| a.partial_cmp(b).unwrap_or(core::cmp::Ordering::Equal))
}
}

View File

@ -34,13 +34,11 @@ use uom::{
ElectricPotential,
ElectricalResistance,
ThermodynamicTemperature,
TemperatureInterval,
},
electric_current::ampere,
electric_potential::volt,
electrical_resistance::ohm,
thermodynamic_temperature::degree_celsius,
temperature_interval::kelvin,
thermodynamic_temperature::{degree_celsius, kelvin},
},
};
@ -245,7 +243,7 @@ impl Handler {
use super::command_parser::ShParameter::*;
match parameter {
T0 => sh.t0 = ThermodynamicTemperature::new::<degree_celsius>(value),
B => sh.b = TemperatureInterval::new::<kelvin>(value),
B => sh.b = ThermodynamicTemperature::new::<kelvin>(value),
R0 => sh.r0 = ElectricalResistance::new::<ohm>(value),
}
send_line(socket, b"{}");
@ -347,7 +345,7 @@ impl Handler {
fn set_fan(socket: &mut TcpSocket, fan_pwm: u32, fan_ctrl: &mut FanCtrl) -> Result<Handler, Error> {
if !fan_ctrl.fan_available() {
send_line(socket, b"{ \"warning\": \"this thermostat doesn't have a fan!\" }");
send_line(socket, b"{ \"warning\": \"this thermostat doesn't have fan!\" }");
return Ok(Handler::Handled);
}
fan_ctrl.set_auto_mode(false);
@ -376,7 +374,7 @@ impl Handler {
fn fan_auto(socket: &mut TcpSocket, fan_ctrl: &mut FanCtrl) -> Result<Handler, Error> {
if !fan_ctrl.fan_available() {
send_line(socket, b"{ \"warning\": \"this thermostat doesn't have a fan!\" }");
send_line(socket, b"{ \"warning\": \"this thermostat doesn't have fan!\" }");
return Ok(Handler::Handled);
}
fan_ctrl.set_auto_mode(true);

View File

@ -3,12 +3,10 @@ use uom::si::{
f64::{
ElectricalResistance,
ThermodynamicTemperature,
TemperatureInterval,
},
electrical_resistance::ohm,
ratio::ratio,
thermodynamic_temperature::{degree_celsius, kelvin},
temperature_interval::kelvin as kelvin_interval,
};
use serde::{Deserialize, Serialize};
@ -20,18 +18,14 @@ pub struct Parameters {
/// Resistance at base temperature
pub r0: ElectricalResistance,
/// Beta
pub b: TemperatureInterval,
pub b: ThermodynamicTemperature,
}
impl Parameters {
/// Perform the resistance to temperature conversion.
pub fn get_temperature(&self, r: ElectricalResistance) -> ThermodynamicTemperature {
let t0 = TemperatureInterval::new::<kelvin_interval>(self.t0.get::<kelvin>());
let inv_temp = 1.0 / t0 + (r / self.r0).get::<ratio>().ln() / self.b;
let temp = 1.0 / inv_temp;
ThermodynamicTemperature::new::<kelvin>(temp.get::<kelvin_interval>())
let inv_temp = 1.0 / self.t0.get::<kelvin>() + (r / self.r0).get::<ratio>().ln() / self.b.get::<kelvin>();
ThermodynamicTemperature::new::<kelvin>(1.0 / inv_temp)
}
}
@ -40,7 +34,7 @@ impl Default for Parameters {
Parameters {
t0: ThermodynamicTemperature::new::<degree_celsius>(25.0),
r0: ElectricalResistance::new::<ohm>(10_000.0),
b: TemperatureInterval::new::<kelvin_interval>(3800.0),
b: ThermodynamicTemperature::new::<kelvin>(3800.0),
}
}
}