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 {
|
||||
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 {
|
||||
state = .connected
|
||||
sendCommand(buildSysexGetConfig())
|
||||
sendCommand(buildSysexGetCellK())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ let RSP_CL_RESULT: UInt8 = 0x0D
|
|||
let RSP_CL_END: UInt8 = 0x0E
|
||||
let RSP_PH_RESULT: UInt8 = 0x0F
|
||||
let RSP_TEMP: UInt8 = 0x10
|
||||
let RSP_CELL_K: UInt8 = 0x11
|
||||
let RSP_REF_FRAME: UInt8 = 0x20
|
||||
let RSP_REF_LP_RANGE: UInt8 = 0x21
|
||||
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_PH: UInt8 = 0x24
|
||||
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_GET_REFS: UInt8 = 0x31
|
||||
let CMD_CLEAR_REFS: UInt8 = 0x32
|
||||
|
|
@ -119,6 +122,7 @@ enum EisMessage {
|
|||
case refLpRange(mode: UInt8, lowIdx: UInt8, highIdx: UInt8)
|
||||
case refsDone
|
||||
case refStatus(hasRefs: Bool)
|
||||
case cellK(Float)
|
||||
}
|
||||
|
||||
// MARK: - Response parser
|
||||
|
|
@ -247,6 +251,9 @@ func parseSysex(_ data: [UInt8]) -> EisMessage? {
|
|||
case RSP_REF_STATUS where p.count >= 1:
|
||||
return .refStatus(hasRefs: p[0] != 0)
|
||||
|
||||
case RSP_CELL_K where p.count >= 5:
|
||||
return .cellK(decodeFloat(p, at: 0))
|
||||
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
|
@ -353,3 +360,14 @@ func buildSysexGetRefs() -> [UInt8] {
|
|||
func buildSysexClearRefs() -> [UInt8] {
|
||||
[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))
|
||||
state.calRs = Double(rs)
|
||||
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)
|
||||
}
|
||||
.disabled(state.eisPoints.isEmpty)
|
||||
|
|
|
|||
|
|
@ -571,6 +571,7 @@ impl App {
|
|||
self.cmd_tx = Some(tx);
|
||||
self.ble_connected = true;
|
||||
self.send_cmd(&protocol::build_sysex_get_config());
|
||||
self.send_cmd(&protocol::build_sysex_get_cell_k());
|
||||
}
|
||||
Message::BleStatus(s) => {
|
||||
if s.contains("Reconnecting") || s.contains("Looking") {
|
||||
|
|
@ -740,6 +741,10 @@ impl App {
|
|||
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) => {
|
||||
if t == Tab::Browse {
|
||||
|
|
@ -951,6 +956,7 @@ impl App {
|
|||
if let Some(rs) = extract_rs(&self.eis_points) {
|
||||
let k = cell_constant(kappa, rs);
|
||||
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);
|
||||
} else {
|
||||
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_LP_RANGE: u8 = 0x21;
|
||||
pub const RSP_REFS_DONE: u8 = 0x22;
|
||||
pub const RSP_CELL_K: u8 = 0x11;
|
||||
pub const RSP_REF_STATUS: u8 = 0x23;
|
||||
|
||||
/* Cue → ESP32 */
|
||||
|
|
@ -41,6 +42,8 @@ pub const CMD_GET_TEMP: u8 = 0x17;
|
|||
pub const CMD_START_CL: u8 = 0x23;
|
||||
pub const CMD_START_PH: u8 = 0x24;
|
||||
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_GET_REFS: u8 = 0x31;
|
||||
pub const CMD_CLEAR_REFS: u8 = 0x32;
|
||||
|
|
@ -254,6 +257,7 @@ pub enum EisMessage {
|
|||
RefLpRange { mode: u8, low_idx: u8, high_idx: u8 },
|
||||
RefsDone,
|
||||
RefStatus { has_refs: bool },
|
||||
CellK(f32),
|
||||
}
|
||||
|
||||
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 => {
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
|
@ -508,3 +516,14 @@ pub fn build_sysex_get_refs() -> Vec<u8> {
|
|||
pub fn build_sysex_clear_refs() -> Vec<u8> {
|
||||
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