apps: sync cell constant K with device, verify export format compatibility
This commit is contained in:
parent
4e0dfecce0
commit
34b298dfe2
|
|
@ -270,6 +270,10 @@ final class AppState {
|
||||||
if !hasRefs {
|
if !hasRefs {
|
||||||
status = "No device refs"
|
status = "No device refs"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case .cellK(let k):
|
||||||
|
calCellConstant = Double(k)
|
||||||
|
status = String(format: "Device cell constant: %.4f cm\u{207B}\u{00B9}", k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -209,6 +209,7 @@ extension BLEManager: CBPeripheralDelegate {
|
||||||
if characteristic.isNotifying {
|
if characteristic.isNotifying {
|
||||||
state = .connected
|
state = .connected
|
||||||
sendCommand(buildSysexGetConfig())
|
sendCommand(buildSysexGetConfig())
|
||||||
|
sendCommand(buildSysexGetCellK())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ let RSP_CL_RESULT: UInt8 = 0x0D
|
||||||
let RSP_CL_END: UInt8 = 0x0E
|
let RSP_CL_END: UInt8 = 0x0E
|
||||||
let RSP_PH_RESULT: UInt8 = 0x0F
|
let RSP_PH_RESULT: UInt8 = 0x0F
|
||||||
let RSP_TEMP: UInt8 = 0x10
|
let RSP_TEMP: UInt8 = 0x10
|
||||||
|
let RSP_CELL_K: UInt8 = 0x11
|
||||||
let RSP_REF_FRAME: UInt8 = 0x20
|
let RSP_REF_FRAME: UInt8 = 0x20
|
||||||
let RSP_REF_LP_RANGE: UInt8 = 0x21
|
let RSP_REF_LP_RANGE: UInt8 = 0x21
|
||||||
let RSP_REFS_DONE: UInt8 = 0x22
|
let RSP_REFS_DONE: UInt8 = 0x22
|
||||||
|
|
@ -43,6 +44,8 @@ let CMD_STOP_AMP: UInt8 = 0x22
|
||||||
let CMD_START_CL: UInt8 = 0x23
|
let CMD_START_CL: UInt8 = 0x23
|
||||||
let CMD_START_PH: UInt8 = 0x24
|
let CMD_START_PH: UInt8 = 0x24
|
||||||
let CMD_START_CLEAN: UInt8 = 0x25
|
let CMD_START_CLEAN: UInt8 = 0x25
|
||||||
|
let CMD_SET_CELL_K: UInt8 = 0x28
|
||||||
|
let CMD_GET_CELL_K: UInt8 = 0x29
|
||||||
let CMD_START_REFS: UInt8 = 0x30
|
let CMD_START_REFS: UInt8 = 0x30
|
||||||
let CMD_GET_REFS: UInt8 = 0x31
|
let CMD_GET_REFS: UInt8 = 0x31
|
||||||
let CMD_CLEAR_REFS: UInt8 = 0x32
|
let CMD_CLEAR_REFS: UInt8 = 0x32
|
||||||
|
|
@ -119,6 +122,7 @@ enum EisMessage {
|
||||||
case refLpRange(mode: UInt8, lowIdx: UInt8, highIdx: UInt8)
|
case refLpRange(mode: UInt8, lowIdx: UInt8, highIdx: UInt8)
|
||||||
case refsDone
|
case refsDone
|
||||||
case refStatus(hasRefs: Bool)
|
case refStatus(hasRefs: Bool)
|
||||||
|
case cellK(Float)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Response parser
|
// MARK: - Response parser
|
||||||
|
|
@ -247,6 +251,9 @@ func parseSysex(_ data: [UInt8]) -> EisMessage? {
|
||||||
case RSP_REF_STATUS where p.count >= 1:
|
case RSP_REF_STATUS where p.count >= 1:
|
||||||
return .refStatus(hasRefs: p[0] != 0)
|
return .refStatus(hasRefs: p[0] != 0)
|
||||||
|
|
||||||
|
case RSP_CELL_K where p.count >= 5:
|
||||||
|
return .cellK(decodeFloat(p, at: 0))
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -353,3 +360,14 @@ func buildSysexGetRefs() -> [UInt8] {
|
||||||
func buildSysexClearRefs() -> [UInt8] {
|
func buildSysexClearRefs() -> [UInt8] {
|
||||||
[0xF0, sysexMfr, CMD_CLEAR_REFS, 0xF7]
|
[0xF0, sysexMfr, CMD_CLEAR_REFS, 0xF7]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func buildSysexSetCellK(_ k: Float) -> [UInt8] {
|
||||||
|
var sx: [UInt8] = [0xF0, sysexMfr, CMD_SET_CELL_K]
|
||||||
|
sx.append(contentsOf: encodeFloat(k))
|
||||||
|
sx.append(0xF7)
|
||||||
|
return sx
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildSysexGetCellK() -> [UInt8] {
|
||||||
|
[0xF0, sysexMfr, CMD_GET_CELL_K, 0xF7]
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,7 @@ struct CalibrateView: View {
|
||||||
let k = cellConstant(kappaMsCm: kappa, rsOhm: Double(rs))
|
let k = cellConstant(kappaMsCm: kappa, rsOhm: Double(rs))
|
||||||
state.calRs = Double(rs)
|
state.calRs = Double(rs)
|
||||||
state.calCellConstant = k
|
state.calCellConstant = k
|
||||||
|
state.send(buildSysexSetCellK(Float(k)))
|
||||||
state.status = String(format: "K = %.4f cm\u{207B}\u{00B9} (Rs = %.1f \u{2126})", k, rs)
|
state.status = String(format: "K = %.4f cm\u{207B}\u{00B9} (Rs = %.1f \u{2126})", k, rs)
|
||||||
}
|
}
|
||||||
.disabled(state.eisPoints.isEmpty)
|
.disabled(state.eisPoints.isEmpty)
|
||||||
|
|
|
||||||
|
|
@ -571,6 +571,7 @@ impl App {
|
||||||
self.cmd_tx = Some(tx);
|
self.cmd_tx = Some(tx);
|
||||||
self.ble_connected = true;
|
self.ble_connected = true;
|
||||||
self.send_cmd(&protocol::build_sysex_get_config());
|
self.send_cmd(&protocol::build_sysex_get_config());
|
||||||
|
self.send_cmd(&protocol::build_sysex_get_cell_k());
|
||||||
}
|
}
|
||||||
Message::BleStatus(s) => {
|
Message::BleStatus(s) => {
|
||||||
if s.contains("Reconnecting") || s.contains("Looking") {
|
if s.contains("Reconnecting") || s.contains("Looking") {
|
||||||
|
|
@ -740,6 +741,10 @@ impl App {
|
||||||
self.status = "No device refs".into();
|
self.status = "No device refs".into();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
EisMessage::CellK(k) => {
|
||||||
|
self.cal_cell_constant = Some(k);
|
||||||
|
self.status = format!("Device cell constant: {:.4} cm-1", k);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Message::TabSelected(t) => {
|
Message::TabSelected(t) => {
|
||||||
if t == Tab::Browse {
|
if t == Tab::Browse {
|
||||||
|
|
@ -951,6 +956,7 @@ impl App {
|
||||||
if let Some(rs) = extract_rs(&self.eis_points) {
|
if let Some(rs) = extract_rs(&self.eis_points) {
|
||||||
let k = cell_constant(kappa, rs);
|
let k = cell_constant(kappa, rs);
|
||||||
self.cal_cell_constant = Some(k);
|
self.cal_cell_constant = Some(k);
|
||||||
|
self.send_cmd(&protocol::build_sysex_set_cell_k(k));
|
||||||
self.status = format!("Cell constant: {:.4} cm-1 (Rs={:.1} ohm)", k, rs);
|
self.status = format!("Cell constant: {:.4} cm-1 (Rs={:.1} ohm)", k, rs);
|
||||||
} else {
|
} else {
|
||||||
self.status = "No valid EIS data for Rs extraction".into();
|
self.status = "No valid EIS data for Rs extraction".into();
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ pub const RSP_TEMP: u8 = 0x10;
|
||||||
pub const RSP_REF_FRAME: u8 = 0x20;
|
pub const RSP_REF_FRAME: u8 = 0x20;
|
||||||
pub const RSP_REF_LP_RANGE: u8 = 0x21;
|
pub const RSP_REF_LP_RANGE: u8 = 0x21;
|
||||||
pub const RSP_REFS_DONE: u8 = 0x22;
|
pub const RSP_REFS_DONE: u8 = 0x22;
|
||||||
|
pub const RSP_CELL_K: u8 = 0x11;
|
||||||
pub const RSP_REF_STATUS: u8 = 0x23;
|
pub const RSP_REF_STATUS: u8 = 0x23;
|
||||||
|
|
||||||
/* Cue → ESP32 */
|
/* Cue → ESP32 */
|
||||||
|
|
@ -41,6 +42,8 @@ pub const CMD_GET_TEMP: u8 = 0x17;
|
||||||
pub const CMD_START_CL: u8 = 0x23;
|
pub const CMD_START_CL: u8 = 0x23;
|
||||||
pub const CMD_START_PH: u8 = 0x24;
|
pub const CMD_START_PH: u8 = 0x24;
|
||||||
pub const CMD_START_CLEAN: u8 = 0x25;
|
pub const CMD_START_CLEAN: u8 = 0x25;
|
||||||
|
pub const CMD_SET_CELL_K: u8 = 0x28;
|
||||||
|
pub const CMD_GET_CELL_K: u8 = 0x29;
|
||||||
pub const CMD_START_REFS: u8 = 0x30;
|
pub const CMD_START_REFS: u8 = 0x30;
|
||||||
pub const CMD_GET_REFS: u8 = 0x31;
|
pub const CMD_GET_REFS: u8 = 0x31;
|
||||||
pub const CMD_CLEAR_REFS: u8 = 0x32;
|
pub const CMD_CLEAR_REFS: u8 = 0x32;
|
||||||
|
|
@ -254,6 +257,7 @@ pub enum EisMessage {
|
||||||
RefLpRange { mode: u8, low_idx: u8, high_idx: u8 },
|
RefLpRange { mode: u8, low_idx: u8, high_idx: u8 },
|
||||||
RefsDone,
|
RefsDone,
|
||||||
RefStatus { has_refs: bool },
|
RefStatus { has_refs: bool },
|
||||||
|
CellK(f32),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode_u16(data: &[u8]) -> u16 {
|
fn decode_u16(data: &[u8]) -> u16 {
|
||||||
|
|
@ -405,6 +409,10 @@ pub fn parse_sysex(data: &[u8]) -> Option<EisMessage> {
|
||||||
RSP_REF_STATUS if data.len() >= 3 => {
|
RSP_REF_STATUS if data.len() >= 3 => {
|
||||||
Some(EisMessage::RefStatus { has_refs: data[2] != 0 })
|
Some(EisMessage::RefStatus { has_refs: data[2] != 0 })
|
||||||
}
|
}
|
||||||
|
RSP_CELL_K if data.len() >= 7 => {
|
||||||
|
let p = &data[2..];
|
||||||
|
Some(EisMessage::CellK(decode_float(&p[0..5])))
|
||||||
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -508,3 +516,14 @@ pub fn build_sysex_get_refs() -> Vec<u8> {
|
||||||
pub fn build_sysex_clear_refs() -> Vec<u8> {
|
pub fn build_sysex_clear_refs() -> Vec<u8> {
|
||||||
vec![0xF0, SYSEX_MFR, CMD_CLEAR_REFS, 0xF7]
|
vec![0xF0, SYSEX_MFR, CMD_CLEAR_REFS, 0xF7]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn build_sysex_set_cell_k(k: f32) -> Vec<u8> {
|
||||||
|
let mut sx = vec![0xF0, SYSEX_MFR, CMD_SET_CELL_K];
|
||||||
|
sx.extend_from_slice(&encode_float(k));
|
||||||
|
sx.push(0xF7);
|
||||||
|
sx
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build_sysex_get_cell_k() -> Vec<u8> {
|
||||||
|
vec![0xF0, SYSEX_MFR, CMD_GET_CELL_K, 0xF7]
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue